Daxia Blog
Uncategorized | Rust | WebUI | FHIR | Javascript | KB

Svelte组件:Steper

起由

在开发产品时,需要一个按照步骤进行配置的界面设计。查看了一些现有的方案后,决定自己来实现这个简单的功能。

效果

Steper

代码

Steper组件定义在文件Steper.svelte中,代码如下:

<script>
    /** 
     * @type (string[])  - 每个步进的显示名称
     */
	export let steps = [];
	export let currentActive = 1;

	$: current_width = (currentActive - 1) / (steps.length - 1) * 100 + '%';
	
    /**
     * 
     * @param {number} stepIncrement - 步进, 例如: 1, -1
     */
	export const handleProgress = (stepIncrement) => {
		if(stepIncrement == 1){
			currentActive++
			if(currentActive > steps.length) {
					currentActive = steps.length
			}
		} else {
			currentActive--
			if(currentActive < 1) {
					currentActive = 1 
			}
		}
	}
</script>

<div class="progress-container">
	<div class="progress" style:width={current_width} />
	{#each steps as step, i}
	<div class="circle" class:active={i < currentActive} data-title={step} >{i+1}</div>
	{/each}
</div>

<style>
	.progress-container {
		display: flex;
		justify-content: space-between;
		position: relative;
		margin-bottom: 30px;
		max-width: 100%;
		width: 350px;
	}

	.progress-container::before {
		content: '';
		background-color: #e0e0e0;
		position: absolute;
		top: 50%;
		left: 0;
		transform: translateY(-50%);
		height: 4px;
		width: 100%;
		z-index: -1;
	}

	.progress {
		background-color: #3498db;
		position: absolute;
		top: 50%;
		left: 0;
		transform: translateY(-50%);
		height: 4px;
		width: 0%;
		z-index: -1;
		transition: 0.4s ease;
	}

	.circle {
		background-color: #fff;
		color: #999;
		border-radius: 50%;
		height: 30px;
		width: 30px;
		display: flex;
		align-items: center;
		justify-content: center;
		border: 3px solid #e0e0e0;
		transition: 0.4s ease;
		cursor: pointer;
	}
	
	.circle::after{
		content: attr(data-title) " ";
		position: absolute;
		bottom: 35px;
		color: #999;
		transition: 0.4s ease;
	}
	
	.circle.active::after {
		color: #3498db;
	}

	.circle.active {
		border-color: #3498db;
	}
</style>

那么如何使用呢?

<script>
    import Steper from '$lib/components/Steper.svelte';
</script>
  
<form class="w-full flex flex-col items-center mt-6">
    <Steper {steps} bind:currentActive bind:this={steper}/>
  
    <div class="w-full h-[300px]">
        {#if currentActive == 1}
        <div class="w-full h-full flex flex-col items-center justify-center">Info</div>
        {:else if currentActive == 2}
        <div class="w-full h-full flex flex-col items-center justify-center">Topic</div>
        {:else if currentActive == 3}
        <div class="w-full h-full flex flex-col items-center justify-center">Mode</div>
        {/if}
    </div>

    <div class="w-full flex mt-4">
      <Button class="w-24" on:click={prevStep}>Prev</Button>
      {#if currentActive < steps.length}
      <Button class="w-24 ml-auto" on:click={nextStep}>Next</Button>
      {:else}
      <Button class="w-24 ml-auto" variant="destructive" on:click={createProject}>Create</Button>
      {/if}
    </div>
</form>

About Daxia
我是一名独立开发者,国家工信部认证高级系统架构设计师,在健康信息化领域与许多组织合作。具备大型卫生信息化平台产品架构、设计和开发的能力,从事软件研发、服务咨询、解决方案、行业标准编著相关工作。
我对健康信息化非常感兴趣,尤其是与HL7和FHIR标准的健康互操作性。我是HL7中国委员会成员,从事FHIR培训讲师和FHIR测评现场指导。
我还是FHIR Chi的作者,这是一款用于FHIR测评的工具。