Quellcode durchsuchen

[stdf]Add Stepper com[onent

dufu1991 vor 2 Jahren
Ursprung
Commit
167c1f21eb

+ 1 - 0
packages/stdf/assets/svg_base/ri-add-line.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M11 11V5H13V11H19V13H13V19H11V13H5V11H11Z"></path></svg>

+ 1 - 0
packages/stdf/assets/svg_base/ri-subtract-line.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M5 11V13H19V11H5Z"></path></svg>

+ 2 - 0
packages/stdf/components/index.js

@@ -34,6 +34,7 @@ import RadioGroup from './radio/RadioGroup.svelte';
 import Rate from './rate/Rate.svelte';
 import Skeleton from './skeleton/Skeleton.svelte';
 import Slider from './slider/Slider.svelte';
+import Stepper from './stepper/Stepper.svelte';
 import Steps from './steps/Steps.svelte';
 import Switch from './switch/Switch.svelte';
 import Swiper from './swiper/Swiper.svelte';
@@ -81,6 +82,7 @@ export {
 	Rate,
 	Skeleton,
 	Slider,
+	Stepper,
 	Steps,
 	Switch,
 	Swiper,

+ 222 - 0
packages/stdf/components/stepper/Stepper.svelte

@@ -0,0 +1,222 @@
+<script>
+	import { createEventDispatcher } from 'svelte';
+	import Icon from '../icon/Icon.svelte';
+	import Loading from '../loading/Loading.svelte';
+	/**
+	 * 当前值
+	 * Current value
+	 * @type {number}
+	 * @range min - max
+	 * @default 0
+	 */
+	export let value = 10;
+
+	/**
+	 * 最小值
+	 * Minimum value
+	 * @type {number}
+	 * @default 0
+	 */
+	export let min = 0;
+
+	/**
+	 * 最大值
+	 * Maximum value
+	 * @type {number}
+	 * @default 100
+	 */
+	export let max = 100;
+
+	/**
+	 * 步长
+	 * Step length
+	 * @type {number}
+	 * @default 1
+	 */
+	export let step = 1;
+
+	/**
+	 * 是否纵向
+	 * Whether it is vertical
+	 * @type {boolean}
+	 * @default false
+	 */
+	export let vertical = false;
+
+	/**
+	 * 强调数字区域
+	 * Highlight the number area
+	 * @type {boolean}
+	 * @default false
+	 */
+	export let numberHighlight = false;
+
+	/**
+	 * 强调区域是否是主题色
+	 * Whether the highlight area is the theme color
+	 * @type {boolean}
+	 * @default true
+	 */
+	export let theme = true;
+
+	/**
+	 * 圆角风格
+	 * Round style
+	 * @type {'none'|'base'|'xl'|'full'}
+	 * @default 'base'
+	 */
+	export let radius = 'base';
+
+	/**
+	 * 对内部显示数字保留小数位数
+	 * The number of decimal places to display internally
+	 * @type {number}
+	 * @default 0
+	 */
+	export let decimal = 0;
+
+	/**
+	 * 是否异步状态
+	 * Whether it is in asynchronous state
+	 * @type {boolean}
+	 * @default false
+	 */
+	export let async = false;
+
+	/**
+	 * 异步状态时,是否显示内部loading
+	 * Whether to show internal loading when in asynchronous state
+	 * @type {boolean}
+	 * @default false
+	 */
+	export let asyncLoading = false;
+
+	/**
+	 * 异步状态时,loading的参数
+	 * Loading parameters when in asynchronous state
+	 * @type {object}
+	 * @default {}
+	 */
+	export let loading = {};
+
+	/**
+	 * 外部有无 padding
+	 * Whether there is external padding
+	 * @type {boolean}
+	 * @default true
+	 */
+	export let padding = true;
+
+	/**
+	 * 外部注入的类
+	 * External injected class
+	 * @type {string}
+	 * @default ''
+	 */
+	export let injClassOut = '';
+
+	/**
+	 * 按钮区域注入的类
+	 * Button area injected class
+	 * @type {string}
+	 * @default ''
+	 */
+	export let injClassBtn = '';
+
+	/**
+	 * 数字区域注入的类
+	 * Number area injected class
+	 * @type {string}
+	 * @default ''
+	 */
+	export let injClassNum = '';
+
+	// 圆角
+	// Round
+	const roundObj = {
+		none: 'rounded-none',
+		base: 'rounded',
+		xl: 'rounded-xl',
+		full: 'rounded-full',
+	};
+
+	const dispatch = createEventDispatcher();
+
+	// 减少
+	// Decrease
+	const decreaseFn = () => {
+		if (!async) {
+			if (value > min) {
+				value = Math.max(min, value - step);
+				dispatch('change', value);
+			}
+		}
+		dispatch('decrease');
+	};
+
+	// 增加
+	// Increase
+	const increaseFn = () => {
+		if (!async) {
+			if (value < max) {
+				value = Math.min(max, value + step);
+				dispatch('change', value);
+			}
+		}
+		dispatch('increase');
+	};
+</script>
+
+<div
+	class="inline-flex items-center bg-gray-100 dark:bg-gray-800 {roundObj[radius] || 'rounded'} {padding
+		? 'p-1'
+		: 'p-0'} overflow-hidden {injClassOut} {vertical ? 'flex-col-reverse' : 'flex-row'}"
+>
+	<button
+		on:click={decreaseFn}
+		class="{vertical ? 'w-full' : 'w-9'} h-9 {roundObj[radius] ||
+			'rounded'} flex flex-col items-center {injClassBtn} justify-center{numberHighlight
+			? ''
+			: theme
+			? ' bg-primary/5 dark:bg-dark/10'
+			: ' bg-white dark:bg-black'}"
+		disabled={async || value === min}
+		aria-label="decrease"
+	>
+		<span class={async || value === min ? 'opacity-20' : ''}>
+			<Icon name="ri-subtract-line" theme={theme && (numberHighlight ? false : true)} />
+		</span>
+	</button>
+
+	{#if async && asyncLoading}
+		<div class="px-2 h-9 {roundObj[radius] || 'rounded'} flex flex-col items-center justify-center">
+			<Loading width="6" height="6" {...loading} />
+		</div>
+	{:else}
+		<div
+			class="px-4 h-9 {roundObj[radius] || 'rounded'} flex flex-col items-center {injClassNum} justify-center{numberHighlight
+				? theme
+					? ' bg-primary/5 text-primary dark:bg-dark/10 dark:text-dark'
+					: ' bg-white dark:bg-black'
+				: ''}"
+		>
+			{value.toFixed(decimal)}
+		</div>
+	{/if}
+
+	<button
+		on:click={increaseFn}
+		class="{vertical ? 'w-full' : 'w-9'} h-9 {roundObj[radius] ||
+			'rounded'} flex flex-col items-center {injClassBtn} justify-center{numberHighlight
+			? ''
+			: theme
+			? ' bg-primary/5 dark:bg-dark/10'
+			: ' bg-white dark:bg-black'}"
+		aria-label="increase"
+		disabled={async || value === max}
+	>
+		<span class={async || value === max ? 'opacity-20' : ''}>
+			<Icon name="ri-add-line" theme={theme && (numberHighlight ? false : true)} />
+		</span>
+	</button>
+</div>

+ 1 - 1
packages/stdf/package.json

@@ -1,6 +1,6 @@
 {
 	"name": "stdf",
-	"version": "0.4.7",
+	"version": "0.5.0",
 	"description": "Mobile web component library based on Svelte and Tailwind",
 	"main": "./components/index.js",
 	"svelte": "./components/index.js",