@hyvor/design 0.0.27 → 0.0.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,7 +8,7 @@ function handleClick() {
8
8
 
9
9
  <IconButton
10
10
  on:click={handleClick}
11
- color="invisible"
11
+ variant="invisible"
12
12
  >
13
13
  {#if $dark}
14
14
  <IconMoonStarsFill size={18} />
@@ -1,11 +1,21 @@
1
1
  <script>export let size = "medium";
2
2
  export let color = "accent";
3
+ export let variant = "fill";
3
4
  export let as = "button";
5
+ const sizes = {
6
+ small: 26,
7
+ medium: 30,
8
+ large: 36
9
+ };
10
+ size = (typeof size === "number" ? size : sizes[size]) + "px";
4
11
  </script>
5
12
 
6
13
  <svelte:element
7
14
  this={as}
8
- class="button {size} {color}"
15
+ class="button {color} {variant}"
16
+
17
+ style:width={size}
18
+ style:height={size}
9
19
 
10
20
  on:keyup
11
21
  on:keydown
@@ -47,42 +57,148 @@ export let as = "button";
47
57
  box-shadow: 0 0 0 calc(var(--local-hover-shadow-size) + 1px) var(--local-hover-shadow-color);
48
58
  }
49
59
 
50
- .button.small {
51
- height: 26px;
52
- width: 26px;
53
- }
54
-
55
- .button.medium {
56
- height: 30px;
57
- width: 30px;
58
- }
59
-
60
60
  .button.large {
61
- height: 36px;
62
- width: 36px;
63
61
  --local-hover-shadow-size: 3px;
64
62
  }
65
63
 
66
- .button.accent {
64
+ .button.fill.accent {
67
65
  background-color: var(--accent);
68
66
  color: var(--accent-text);
69
67
  --local-hover-shadow-color: var(--accent-light);
70
68
  }
71
- .button.soft {
69
+ .button.fill.gray {
70
+ background-color: var(--gray-light);
71
+ color: var(--gray-dark);
72
+ --local-hover-shadow-color: color-mix(in srgb, var(--gray-light) 40%, transparent);
73
+ }
74
+ .button.fill.green {
75
+ background-color: var(--green-light);
76
+ color: var(--green-dark);
77
+ --local-hover-shadow-color: color-mix(in srgb, var(--green-light) 40%, transparent);
78
+ }
79
+ .button.fill.red {
80
+ background-color: var(--red-light);
81
+ color: var(--red-dark);
82
+ --local-hover-shadow-color: color-mix(in srgb, var(--red-light) 40%, transparent);
83
+ }
84
+ .button.fill.blue {
85
+ background-color: var(--blue-light);
86
+ color: var(--blue-dark);
87
+ --local-hover-shadow-color: color-mix(in srgb, var(--blue-light) 40%, transparent);
88
+ }
89
+ .button.fill.orange {
90
+ background-color: var(--orange-light);
91
+ color: var(--orange-dark);
92
+ --local-hover-shadow-color: color-mix(in srgb, var(--orange-light) 40%, transparent);
93
+ }
94
+ .button.outline {
95
+ border: 1px solid;
96
+ }
97
+ .button.outline.accent {
98
+ border-color: var(--accent);
99
+ color: var(--accent);
100
+ --local-hover-shadow-color: var(--accent-light);
101
+ }
102
+ .button.outline.gray {
103
+ background-color: none;
104
+ border-color: var(--gray-dark);
105
+ color: var(--gray-dark);
106
+ --local-hover-shadow-color: var(--gray-light);
107
+ }
108
+ .button.outline.green {
109
+ background-color: none;
110
+ border-color: var(--green-dark);
111
+ color: var(--green-dark);
112
+ --local-hover-shadow-color: var(--green-light);
113
+ }
114
+ .button.outline.red {
115
+ background-color: none;
116
+ border-color: var(--red-dark);
117
+ color: var(--red-dark);
118
+ --local-hover-shadow-color: var(--red-light);
119
+ }
120
+ .button.outline.blue {
121
+ background-color: none;
122
+ border-color: var(--blue-dark);
123
+ color: var(--blue-dark);
124
+ --local-hover-shadow-color: var(--blue-light);
125
+ }
126
+ .button.outline.orange {
127
+ background-color: none;
128
+ border-color: var(--orange-dark);
129
+ color: var(--orange-dark);
130
+ --local-hover-shadow-color: var(--orange-light);
131
+ }
132
+ .button.outline-fill {
133
+ border: 1px solid;
134
+ }
135
+ .button.outline-fill.accent {
72
136
  background-color: var(--accent-light);
137
+ border-color: var(--accent);
73
138
  color: var(--accent);
74
- --local-hover-shadow-color: #eee;
139
+ --local-hover-shadow-color: color-mix(in srgb, var(--accent-light) 40%, transparent);
140
+ }
141
+ .button.outline-fill.gray {
142
+ background-color: var(--gray-light);
143
+ border-color: var(--gray-dark);
144
+ color: var(--gray-dark);
145
+ --local-hover-shadow-color: var(--gray-light);
146
+ }
147
+ .button.outline-fill.green {
148
+ background-color: var(--green-light);
149
+ border-color: var(--green-dark);
150
+ color: var(--green-dark);
151
+ --local-hover-shadow-color: var(--green-light);
152
+ }
153
+ .button.outline-fill.red {
154
+ background-color: var(--red-light);
155
+ border-color: var(--red-dark);
156
+ color: var(--red-dark);
157
+ --local-hover-shadow-color: var(--red-light);
158
+ }
159
+ .button.outline-fill.blue {
160
+ background-color: var(--blue-light);
161
+ border-color: var(--blue-dark);
162
+ color: var(--blue-dark);
163
+ --local-hover-shadow-color: var(--blue-light);
164
+ }
165
+ .button.outline-fill.orange {
166
+ background-color: var(--orange-light);
167
+ border-color: var(--orange-dark);
168
+ color: var(--orange-dark);
169
+ --local-hover-shadow-color: var(--orange-light);
75
170
  }
76
171
  .button.invisible {
77
172
  background-color: transparent;
78
173
  transition: 0.2s background-color;
79
174
  }
80
- .button.invisible:hover {
175
+ .button.invisible.accent:hover {
81
176
  background-color: var(--accent-light);
82
177
  box-shadow: none !important;
178
+ color: var(--text-light);
83
179
  }
84
- .button.danger {
85
- background-color: var(--red-dark);
86
- color: var(--text-white);
87
- --local-hover-shadow-color: var(--red-light);
180
+ .button.invisible.gray:hover {
181
+ background-color: var(--gray-light);
182
+ box-shadow: none !important;
183
+ color: var(--gray-dark);
184
+ }
185
+ .button.invisible.green:hover {
186
+ background-color: var(--green-light);
187
+ box-shadow: none !important;
188
+ color: var(--green-dark);
189
+ }
190
+ .button.invisible.red:hover {
191
+ background-color: var(--red-light);
192
+ box-shadow: none !important;
193
+ color: var(--red-dark);
194
+ }
195
+ .button.invisible.blue:hover {
196
+ background-color: var(--blue-light);
197
+ box-shadow: none !important;
198
+ color: var(--blue-dark);
199
+ }
200
+ .button.invisible.orange:hover {
201
+ background-color: var(--orange-light);
202
+ box-shadow: none !important;
203
+ color: var(--orange-dark);
88
204
  }</style>
@@ -2,8 +2,9 @@ import { SvelteComponent } from "svelte";
2
2
  declare const __propDef: {
3
3
  props: {
4
4
  [x: string]: any;
5
- size?: "small" | "medium" | "large" | undefined;
6
- color?: "danger" | "accent" | "soft" | "invisible" | undefined;
5
+ size?: number | "small" | "medium" | "large" | undefined;
6
+ color?: "accent" | "gray" | "green" | "red" | "blue" | "orange" | undefined;
7
+ variant?: "invisible" | "fill" | "outline" | "outline-fill" | undefined;
7
8
  as?: "button" | "a" | undefined;
8
9
  };
9
10
  events: {
@@ -1,6 +1,20 @@
1
- <script>export let block = false;
1
+ <script>import {
2
+ IconCheckCircleFill,
3
+ IconXCircleFill
4
+ } from "@hyvor/icons";
5
+ export let block = false;
6
+ export let full = false;
2
7
  export let padding = "medium";
3
8
  export let size = "medium";
9
+ export let state = "loading";
10
+ export let duration = 2e3;
11
+ $: {
12
+ if (state === "success" || state === "error") {
13
+ setTimeout(() => {
14
+ state = "none";
15
+ }, duration);
16
+ }
17
+ }
4
18
  export let color = "var(--accent)";
5
19
  export let colorTrack = "var(--accent-lightest)";
6
20
  export let invert = false;
@@ -31,6 +45,10 @@ padding = typeof padding === "number" ? padding : paddings[padding];
31
45
  <div
32
46
  class="loader"
33
47
  class:block
48
+ class:full
49
+ class:success={state === 'success'}
50
+ class:error={state === 'error'}
51
+
34
52
 
35
53
  style:--local-size={size + "px"}
36
54
  style:padding={block ? padding + "px" : undefined}
@@ -38,38 +56,54 @@ padding = typeof padding === "number" ? padding : paddings[padding];
38
56
  >
39
57
 
40
58
 
41
- <span class="loader-wrap">
42
- <svg>
43
- <circle
44
- class="track"
45
- cx="50%"
46
- cy="50%"
47
- r={r + "px"}
48
- fill="none"
49
- stroke-width={strokeWidth}
50
- stroke={colorTrack}
51
- ></circle>
52
- <circle
53
- class="progress"
54
- cx="50%"
55
- cy="50%"
56
- r={r + "px"}
57
- fill="none"
58
- stroke-width={strokeWidth}
59
- stroke={color}
60
- stroke-linecap="round"
61
- stroke-dasharray={strokeDashArray}
62
- stroke-dashoffset={strokeDashOffset}
63
- ></circle>
64
- </svg>
65
- </span>
59
+ {#if state !== 'none'}
60
+ <span class="loader-wrap">
61
+
62
+ {#if state === 'loading'}
63
+ <svg>
64
+ <circle
65
+ class="track"
66
+ cx="50%"
67
+ cy="50%"
68
+ r={r + "px"}
69
+ fill="none"
70
+ stroke-width={strokeWidth}
71
+ stroke={colorTrack}
72
+ ></circle>
73
+ <circle
74
+ class="progress"
75
+ cx="50%"
76
+ cy="50%"
77
+ r={r + "px"}
78
+ fill="none"
79
+ stroke-width={strokeWidth}
80
+ stroke={color}
81
+ stroke-linecap="round"
82
+ stroke-dasharray={strokeDashArray}
83
+ stroke-dashoffset={strokeDashOffset}
84
+ ></circle>
85
+ </svg>
86
+ {:else if state === 'success'}
87
+ <span class="success-icon">
88
+ <IconCheckCircleFill color="var(--green)" width={size} height={size} />
89
+ </span>
90
+ {:else if state === 'error'}
91
+ <span class="error-icon">
92
+ <IconXCircleFill color="var(--red)" width={size} height={size} />
93
+ </span>
94
+ {/if}
95
+
96
+ </span>
97
+
98
+ {/if}
99
+
66
100
 
67
101
  {#if $$slots.default}
68
102
  <div class="message">
69
103
  <slot></slot>
70
104
  </div>
71
105
  {/if}
72
-
106
+
73
107
  </div>
74
108
 
75
109
 
@@ -92,6 +126,19 @@ padding = typeof padding === "number" ? padding : paddings[padding];
92
126
  margin-top: 10px;
93
127
  }
94
128
 
129
+ .loader.full {
130
+ width: 100%;
131
+ height: 100%;
132
+ flex: 1;
133
+ display: flex;
134
+ align-items: center;
135
+ justify-content: center;
136
+ flex-direction: column;
137
+ }
138
+ .loader.full .message {
139
+ margin-top: 10px;
140
+ }
141
+
95
142
  .loader-wrap {
96
143
  display: inline-flex;
97
144
  width: var(--local-size);
@@ -100,6 +147,10 @@ padding = typeof padding === "number" ? padding : paddings[padding];
100
147
  position: relative;
101
148
  }
102
149
 
150
+ .success-icon, .error-icon {
151
+ animation: scale 0.2s ease-in-out;
152
+ }
153
+
103
154
  svg {
104
155
  width: inherit;
105
156
  height: inherit;
@@ -123,4 +174,14 @@ circle.progress {
123
174
  100% {
124
175
  transform: rotate(270deg);
125
176
  }
177
+ }
178
+ @keyframes scale {
179
+ 0% {
180
+ transform: scale(0.5);
181
+ opacity: 0.4;
182
+ }
183
+ 100% {
184
+ transform: scale(1);
185
+ opacity: 1;
186
+ }
126
187
  }</style>
@@ -3,8 +3,11 @@ declare const __propDef: {
3
3
  props: {
4
4
  [x: string]: any;
5
5
  block?: boolean | undefined;
6
+ full?: boolean | undefined;
6
7
  padding?: number | "none" | "small" | "medium" | "large" | undefined;
7
8
  size?: number | "small" | "medium" | "large" | undefined;
9
+ state?: "none" | "error" | "success" | "loading" | undefined;
10
+ duration?: number | undefined;
8
11
  color?: string | undefined;
9
12
  colorTrack?: string | undefined;
10
13
  invert?: boolean | undefined;
@@ -36,7 +36,7 @@ export let closeOnEscape = true;
36
36
 
37
37
  <div class="close-wrap">
38
38
  <IconButton
39
- color="invisible"
39
+ variant="invisible"
40
40
  on:click={() => show = false}
41
41
  >
42
42
  <IconX size={25} />
@@ -92,11 +92,19 @@ input {
92
92
  background: transparent;
93
93
  padding: 0;
94
94
  margin: 0;
95
+ color: inherit;
95
96
  }
96
97
  input:focus {
97
98
  outline: none;
98
99
  }
99
100
 
101
+ .input-wrap.size-x-small {
102
+ padding: 0 15px;
103
+ height: 26px;
104
+ font-size: 12px;
105
+ --local-shadow-size: 1px;
106
+ }
107
+
100
108
  .input-wrap.size-small {
101
109
  padding: 0 15px;
102
110
  height: 30px;
@@ -3,7 +3,7 @@ declare const __propDef: {
3
3
  props: {
4
4
  [x: string]: any;
5
5
  state?: "default" | "error" | "success" | "warning" | undefined;
6
- size?: "small" | "medium" | "large" | undefined;
6
+ size?: "small" | "medium" | "large" | "x-small" | undefined;
7
7
  block?: boolean | undefined;
8
8
  value?: any;
9
9
  };
@@ -3,34 +3,62 @@ export let block = false;
3
3
  export let rows = 5;
4
4
  export let cols = 40;
5
5
  export let state = "default";
6
+ let input;
6
7
  </script>
7
8
 
8
- <textarea
9
- bind:value={value}
10
9
 
11
- on:keyup
12
- on:keydown
13
- on:keypress
14
- on:focus
15
- on:blur
16
- on:click
17
- on:mouseover
18
- on:mouseenter
19
- on:mouseleave
20
- on:change
21
- on:input
10
+ <span class="input-wrap state-{state}"
11
+ class:block
12
+ on:click={() => input.focus()}
13
+ on:keydown={(e) => {
14
+ if (e.key === 'Enter') {
15
+ input.blur();
16
+ }
17
+ }}
18
+ role="textbox"
19
+ tabindex="0"
20
+ >
22
21
 
23
- {rows}
24
- {cols}
22
+ {#if $$slots.start}
23
+ <span class="slot start"
24
+
25
+ >
26
+ <slot name="start" />
27
+ </span>
28
+ {/if}
25
29
 
26
- {...$$restProps}
30
+ <textarea
31
+ bind:value={value}
32
+ bind:this={input}
33
+
27
34
 
28
- class:block
29
- class="state-{state}"
35
+ on:keyup
36
+ on:keydown
37
+ on:keypress
38
+ on:focus
39
+ on:blur
40
+ on:click
41
+ on:mouseover
42
+ on:mouseenter
43
+ on:mouseleave
44
+ on:change
45
+ on:input
46
+
47
+ {rows}
48
+ {cols}
49
+
50
+ {...$$restProps}
30
51
 
31
- ></textarea>
52
+ ></textarea>
53
+
54
+ {#if $$slots.end}
55
+ <span class="slot end">
56
+ <slot name="end" />
57
+ </span>
58
+ {/if}
59
+ </span>
32
60
 
33
- <style>textarea {
61
+ <style>.input-wrap {
34
62
  padding: 10px 15px;
35
63
  background-color: var(--input);
36
64
  transition: 0.2s box-shadow;
@@ -40,40 +68,73 @@ export let state = "default";
40
68
  border: none;
41
69
  transition: 0.2s box-shadow;
42
70
  max-width: 100%;
71
+ color: inherit;
72
+ display: inline-flex;
73
+ resize: vertical;
74
+ overflow: auto;
75
+ align-items: flex-start;
76
+ justify-content: center;
43
77
  --local-shadow-size: 2px;
44
78
  }
45
-
46
- textarea:focus {
79
+ .input-wrap:focus-within {
80
+ outline: 0;
47
81
  box-shadow: 0 0 0 var(--local-shadow-size) var(--accent-light);
48
82
  }
49
83
 
50
- textarea.block {
84
+ .input-wrap.block {
51
85
  display: block;
52
86
  width: 100%;
53
87
  resize: vertical;
54
88
  }
55
89
 
56
- textarea:focus-visible {
90
+ .input-wrap:focus-visible {
57
91
  outline: 0;
58
92
  }
59
93
 
60
- textarea.state-error {
94
+ .input-wrap.state-error {
61
95
  box-shadow: 0 0 0 var(--local-shadow-size) var(--red-light);
62
96
  }
63
- textarea.state-error:focus {
97
+ .input-wrap.state-error:focus-within {
64
98
  box-shadow: 0 0 0 calc(var(--local-shadow-size) + 1px) var(--red-light);
65
99
  }
66
100
 
67
- textarea.state-success {
101
+ .input-wrap.state-success {
68
102
  box-shadow: 0 0 0 2px var(--green-light);
69
103
  }
70
- textarea.state-success:focus {
104
+ .input-wrap.state-success:focus-within {
71
105
  box-shadow: 0 0 0 calc(var(--local-shadow-size) + 1px) var(--green-light);
72
106
  }
73
107
 
74
- textarea.state-warning {
108
+ .input-wrap.state-warning {
75
109
  box-shadow: 0 0 0 2px var(--orange-light);
76
110
  }
77
- textarea.state-warning:focus {
111
+ .input-wrap.state-warning:focus-within {
78
112
  box-shadow: 0 0 0 calc(var(--local-shadow-size) + 1px) var(--orange-light);
113
+ }
114
+
115
+ .input-wrap .slot {
116
+ padding: 0 10px;
117
+ }
118
+
119
+ .input-wrap .slot.start {
120
+ margin-right: 10px;
121
+ }
122
+
123
+ .input-wrap .slot.end {
124
+ margin-left: 10px;
125
+ }
126
+
127
+ .input-wrap textarea {
128
+ flex: 1;
129
+ width: 100%;
130
+ border: none;
131
+ font-family: inherit;
132
+ font-size: inherit;
133
+ background: transparent;
134
+ padding: 0;
135
+ margin: 0;
136
+ resize: none;
137
+ }
138
+ .input-wrap textarea:focus {
139
+ outline: none;
79
140
  }</style>
@@ -23,7 +23,10 @@ declare const __propDef: {
23
23
  } & {
24
24
  [evt: string]: CustomEvent<any>;
25
25
  };
26
- slots: {};
26
+ slots: {
27
+ start: {};
28
+ end: {};
29
+ };
27
30
  };
28
31
  export type TextareaProps = typeof __propDef.props;
29
32
  export type TextareaEvents = typeof __propDef.events;
@@ -44,7 +44,7 @@ function handleCopy() {
44
44
  <Tooltip text={emailCopied ? "Copied!" : "Copy email"} position="top">
45
45
  <IconButton
46
46
  size="small"
47
- color="invisible"
47
+ variant="invisible"
48
48
  on:click={handleCopy}
49
49
  on:mouseleave={() => emailCopied = false}
50
50
  >
@@ -66,7 +66,7 @@ export let darkToggle = true;
66
66
  <span class="mobile-nav-wrap">
67
67
  <Dropdown align="end" width={300}>
68
68
  <IconButton
69
- color="invisible"
69
+ variant="invisible"
70
70
  slot="trigger"
71
71
  >
72
72
  <IconList size={18} />
@@ -47,7 +47,7 @@
47
47
  --hover: #fafafa;
48
48
  --link: #1d85d2;
49
49
 
50
- --input: #e6e6e6;
50
+ --input: #f3f3f3;
51
51
  --input-hover: #ccc; /* checkbox/radio */
52
52
 
53
53
  --box-shadow: 0 0 30px #0000000d;
@@ -75,6 +75,8 @@
75
75
  --link: #7cb6e1;
76
76
  --hover: #232323;
77
77
 
78
+ --input: #333;
79
+
78
80
  }
79
81
 
80
82
  $breakpoint-xs: 320px;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyvor/design",
3
- "version": "0.0.27",
3
+ "version": "0.0.29",
4
4
  "license": "MIT",
5
5
  "private": false,
6
6
  "scripts": {