webcake-ui-kit 1.0.0 → 1.0.1

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.
Files changed (66) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +358 -8
  3. package/package.json +68 -5
  4. package/src/components/accordion/Accordion.vue +70 -0
  5. package/src/components/accordion/accordion.css +5 -0
  6. package/src/components/accordion-item/AccordionItem.vue +98 -0
  7. package/src/components/accordion-item/accordion-item.css +143 -0
  8. package/src/components/alert-dialog/AlertDialog.vue +82 -0
  9. package/src/components/alert-dialog/alert-dialog.css +33 -0
  10. package/src/components/badge/Badge.vue +2 -2
  11. package/src/components/badge/badge.css +1 -4
  12. package/src/components/breadcrumb/Breadcrumb.vue +85 -0
  13. package/src/components/breadcrumb/breadcrumb.css +90 -0
  14. package/src/components/button/Button.vue +77 -10
  15. package/src/components/button/button.css +258 -24
  16. package/src/components/button-group/ButtonGroup.vue +25 -0
  17. package/src/components/button-group/button-group.css +30 -0
  18. package/src/components/checkbox/Checkbox.vue +55 -0
  19. package/src/components/checkbox/checkbox.css +86 -0
  20. package/src/components/checkbox-group/CheckboxGroup.vue +50 -0
  21. package/src/components/checkbox-group/checkbox-group.css +35 -0
  22. package/src/components/dialog/Dialog.vue +355 -0
  23. package/src/components/dialog/dialog.css +255 -0
  24. package/src/components/divider/Divider.vue +35 -0
  25. package/src/components/divider/divider.css +38 -0
  26. package/src/components/input/Input.vue +99 -0
  27. package/src/components/input/input.css +123 -0
  28. package/src/components/pagination/Pagination.vue +211 -0
  29. package/src/components/pagination/pagination.css +13 -0
  30. package/src/components/radio/Radio.vue +74 -0
  31. package/src/components/radio/radio.css +89 -0
  32. package/src/components/radio-group/RadioGroup.vue +70 -0
  33. package/src/components/radio-group/radio_group.css +11 -0
  34. package/src/components/rich-checkbox-group/RichCheckboxGroup.vue +59 -0
  35. package/src/components/rich-checkbox-group/rich-checkbox-group.css +54 -0
  36. package/src/components/rich-switch-group/RichSwitchGroup.vue +49 -0
  37. package/src/components/rich-switch-group/rich_switch_group.css +45 -0
  38. package/src/components/select/Select.vue +262 -0
  39. package/src/components/select/select.css +207 -0
  40. package/src/components/select-option/SelectOption.vue +82 -0
  41. package/src/components/select-option/select_option.css +60 -0
  42. package/src/components/sidebar-group-label/SidebarGroupLabel.vue +68 -0
  43. package/src/components/sidebar-group-label/sidebar_group_label.css +61 -0
  44. package/src/components/sidebar-item/SidebarItem.vue +110 -0
  45. package/src/components/sidebar-item/sidebar_item.css +142 -0
  46. package/src/components/slider/Slider.vue +255 -0
  47. package/src/components/slider/slider.css +89 -0
  48. package/src/components/spinner/Spinner.vue +47 -0
  49. package/src/components/spinner/spinner.css +48 -0
  50. package/src/components/switch/Switch.vue +32 -0
  51. package/src/components/switch/switch.css +46 -0
  52. package/src/components/switch-group/SwitchGroup.vue +32 -0
  53. package/src/components/switch-group/switch_group.css +28 -0
  54. package/src/components/tabs/Tabs.vue +57 -0
  55. package/src/components/tabs/tabs.css +118 -0
  56. package/src/components/tag/Tag.vue +47 -0
  57. package/src/components/tag/tag.css +115 -0
  58. package/src/components/toggle/Toggle.vue +112 -0
  59. package/src/components/toggle/toggle.css +174 -0
  60. package/src/components/toggle-group/ToggleGroup.vue +57 -0
  61. package/src/components/toggle-group/toggle-group.css +68 -0
  62. package/src/icons/LoaderIcon.vue +22 -0
  63. package/src/index.js +29 -2
  64. package/src/styles/border_radius.css +3 -3
  65. package/src/styles/color_general.css +21 -14
  66. package/src/styles/shadow.css +2 -2
@@ -1,42 +1,276 @@
1
+ /* ============================================================
2
+ Base
3
+ ============================================================ */
1
4
  .ui-btn {
2
- padding: 8px 16px;
3
- border: none;
4
- border-radius: 6px;
5
+ display: inline-flex;
6
+ align-items: center;
7
+ justify-content: center;
8
+ border: 1px solid transparent;
9
+ margin: 0;
5
10
  cursor: pointer;
6
- font-weight: 500;
11
+ font-family: var(--font-family-body);
12
+ font-weight: var(--paragraph-medium-font-weight);
13
+ text-align: center;
14
+ white-space: nowrap;
15
+ transition:
16
+ background-color 0.12s ease,
17
+ border-color 0.12s ease,
18
+ color 0.12s ease;
19
+ -webkit-appearance: none;
7
20
  }
8
21
 
22
+ .ui-btn__label {
23
+ display: inline-flex;
24
+ }
25
+
26
+ .ui-btn__icon {
27
+ display: inline-flex;
28
+ align-items: center;
29
+ justify-content: center;
30
+ flex-shrink: 0;
31
+ overflow: hidden;
32
+ }
33
+
34
+ /* ============================================================
35
+ Sizes
36
+ ============================================================ */
37
+ .ui-btn--xs {
38
+ height: 24px;
39
+ padding: var(--spacing-3) var(--spacing-xs);
40
+ gap: var(--spacing-6);
41
+ font-size: var(--paragraph-mini-font-size);
42
+ line-height: var(--paragraph-mini-line-height);
43
+ letter-spacing: var(--paragraph-mini-letter-spacing);
44
+ }
45
+ .ui-btn--xs .ui-btn__icon,
46
+ .ui-btn--xs :deep(svg) {
47
+ width: 16px;
48
+ height: 16px;
49
+ }
50
+
51
+ .ui-btn--sm {
52
+ height: 32px;
53
+ padding: var(--spacing-6) var(--spacing-sm);
54
+ gap: var(--spacing-6);
55
+ font-size: var(--paragraph-small-font-size);
56
+ line-height: var(--paragraph-small-line-height);
57
+ letter-spacing: var(--paragraph-small-letter-spacing);
58
+ }
59
+ .ui-btn--sm .ui-btn__icon,
60
+ .ui-btn--sm :deep(svg) {
61
+ width: 20px;
62
+ height: 20px;
63
+ }
64
+
65
+ .ui-btn--md {
66
+ height: 36px;
67
+ padding: var(--spacing-xs) var(--spacing-md);
68
+ gap: var(--spacing-xs);
69
+ font-size: var(--paragraph-small-font-size);
70
+ line-height: var(--paragraph-small-line-height);
71
+ letter-spacing: var(--paragraph-small-letter-spacing);
72
+ }
73
+ .ui-btn--md .ui-btn__icon,
74
+ .ui-btn--md :deep(svg) {
75
+ width: 20px;
76
+ height: 20px;
77
+ }
78
+
79
+ .ui-btn--lg {
80
+ height: 40px;
81
+ padding: var(--spacing-10) var(--spacing-xl);
82
+ gap: var(--spacing-xs);
83
+ font-size: var(--paragraph-small-font-size);
84
+ line-height: var(--paragraph-small-line-height);
85
+ letter-spacing: var(--paragraph-small-letter-spacing);
86
+ }
87
+ .ui-btn--lg .ui-btn__icon,
88
+ .ui-btn--lg :deep(svg) {
89
+ width: 20px;
90
+ height: 20px;
91
+ }
92
+
93
+ .ui-btn--xl {
94
+ height: 48px;
95
+ padding: var(--spacing-sm) var(--spacing-2xl);
96
+ gap: var(--spacing-xs);
97
+ font-size: var(--paragraph-regular-font-size);
98
+ line-height: var(--paragraph-regular-line-height);
99
+ letter-spacing: var(--paragraph-regular-letter-spacing);
100
+ }
101
+ .ui-btn--xl .ui-btn__icon,
102
+ .ui-btn--xl :deep(svg) {
103
+ width: 20px;
104
+ height: 20px;
105
+ }
106
+
107
+ /* ============================================================
108
+ Roundness
109
+ - mini (xs) uses rounded-lg by default; other sizes use 10px.
110
+ - round = full pill across all sizes.
111
+ ============================================================ */
112
+ .ui-btn--round-default {
113
+ border-radius: var(--radius-10);
114
+ }
115
+ .ui-btn--xs.ui-btn--round-default {
116
+ border-radius: var(--rounded-lg);
117
+ }
118
+ .ui-btn--round-round {
119
+ border-radius: var(--rounded-full);
120
+ }
121
+
122
+ /* ============================================================
123
+ Variants
124
+ ============================================================ */
125
+
126
+ /* Primary */
9
127
  .ui-btn--primary {
10
- background: #3b82f6;
11
- color: white;
128
+ background: var(--primary-brand-bg);
129
+ color: var(--inverse-fg);
130
+ }
131
+ .ui-btn--primary:hover,
132
+ .ui-btn--primary:active {
133
+ background: var(--primary-brand-hover);
134
+ }
135
+
136
+ /* Neutral */
137
+ .ui-btn--neutral {
138
+ background: var(--button-black);
139
+ color: var(--button-black-fg);
140
+ }
141
+ .ui-btn--neutral:hover,
142
+ .ui-btn--neutral:active {
143
+ background: var(--button-black-hover);
12
144
  }
145
+
146
+ /* Secondary */
13
147
  .ui-btn--secondary {
14
- background: #6b7280;
15
- color: white;
148
+ background: var(--secondary-bg);
149
+ color: var(--secondary-fg);
150
+ }
151
+ .ui-btn--secondary:hover,
152
+ .ui-btn--secondary:active {
153
+ background: var(--secondary-hover);
16
154
  }
17
- .ui-btn--danger {
18
- background: #ef4444;
19
- color: white;
155
+
156
+ /* Outline */
157
+ .ui-btn--outline {
158
+ background: var(--primary-bg);
159
+ color: var(--primary-fg);
160
+ border: 1px solid var(--border-primary);
161
+ box-shadow: var(--shadow-xs);
20
162
  }
21
- .ui-btn--success {
22
- background: #10b981;
23
- color: white;
163
+ .ui-btn--outline:hover,
164
+ .ui-btn--outline:active {
165
+ background: var(--outline-hover);
166
+ box-shadow: none;
24
167
  }
25
168
 
26
- .ui-btn--small {
27
- padding: 6px 12px;
28
- font-size: 14px;
169
+ /* Ghost */
170
+ .ui-btn--ghost {
171
+ background: var(--ghost);
172
+ color: var(--primary-fg);
173
+ }
174
+ .ui-btn--ghost:hover,
175
+ .ui-btn--ghost:active {
176
+ background: var(--ghost-hover);
177
+ }
178
+
179
+ /* Destructive */
180
+ .ui-btn--destructive {
181
+ background: var(--destructive);
182
+ color: var(--destructive-inverse-fg);
183
+ }
184
+ .ui-btn--destructive:hover,
185
+ .ui-btn--destructive:active {
186
+ background: var(--destructive-hover);
29
187
  }
30
- .ui-btn--medium {
31
- padding: 8px 16px;
32
- font-size: 16px;
188
+
189
+ /* Link — text-only button on transparent ghost bg, brand-colored. */
190
+ .ui-btn--link {
191
+ background: var(--ghost);
192
+ color: var(--primary-brand-fg);
33
193
  }
34
- .ui-btn--large {
35
- padding: 12px 20px;
36
- font-size: 18px;
194
+ .ui-btn--link:hover,
195
+ .ui-btn--link:active {
196
+ color: var(--primary-brand-hover);
37
197
  }
38
198
 
199
+ /* ============================================================
200
+ Focus
201
+ ============================================================ */
202
+ .ui-btn:focus {
203
+ outline: none;
204
+ }
205
+ .ui-btn:focus-visible {
206
+ outline: none;
207
+ box-shadow: 0 0 0 3px var(--focus-ring);
208
+ }
209
+ .ui-btn--secondary:focus-visible {
210
+ background: var(--secondary-hover);
211
+ }
212
+ .ui-btn--outline:focus-visible {
213
+ border-color: var(--border-focus);
214
+ }
215
+ .ui-btn--destructive:focus-visible {
216
+ box-shadow: 0 0 0 3px var(--focus-ring-error);
217
+ }
218
+ /* ============================================================
219
+ Disabled
220
+ ============================================================ */
39
221
  .ui-btn:disabled {
40
- opacity: 0.6;
222
+ opacity: 0.5;
41
223
  cursor: not-allowed;
224
+ pointer-events: none;
225
+ }
226
+
227
+ /* ============================================================
228
+ Icon-only — square button, uniform padding per size.
229
+ Width = height; default slot content rendered in .ui-btn__icon
230
+ so the existing per-size icon sizing applies (16 for xs, 20
231
+ otherwise).
232
+ ============================================================ */
233
+ .ui-btn--icon-only {
234
+ gap: 0;
235
+ }
236
+
237
+ .ui-btn--icon-only.ui-btn--xs {
238
+ min-width: 24px;
239
+ padding: var(--spacing-3xs);
240
+ }
241
+ .ui-btn--icon-only.ui-btn--sm {
242
+ min-width: 32px;
243
+ padding: var(--spacing-6);
244
+ }
245
+ .ui-btn--icon-only.ui-btn--md {
246
+ min-width: 36px;
247
+ padding: var(--spacing-xs);
248
+ }
249
+ .ui-btn--icon-only.ui-btn--lg {
250
+ min-width: 40px;
251
+ padding: var(--spacing-10);
252
+ }
253
+ .ui-btn--icon-only.ui-btn--xl {
254
+ min-width: 48px;
255
+ padding: var(--spacing-sm);
256
+ }
257
+
258
+ /* ============================================================
259
+ Loading — spinner replaces left icon, click suppressed.
260
+ Spinner inherits currentColor so it matches the variant fg.
261
+ ============================================================ */
262
+ .ui-btn--loading {
263
+ cursor: progress;
264
+ }
265
+
266
+ .ui-btn__spinner {
267
+ animation: ui-btn-spin 0.7s linear infinite;
268
+ transform-origin: center center;
269
+ opacity: 0.85;
270
+ }
271
+
272
+ @keyframes ui-btn-spin {
273
+ to {
274
+ transform: rotate(360deg);
275
+ }
42
276
  }
@@ -0,0 +1,25 @@
1
+ <template>
2
+ <div class="ui-button-group" role="group" :aria-label="label || undefined" @click="onClick">
3
+ <slot />
4
+ </div>
5
+ </template>
6
+
7
+ <script>
8
+ export default {
9
+ name: 'ButtonGroup',
10
+ props: {
11
+ label: { type: String, default: '' }
12
+ },
13
+ emits: ['click'],
14
+ methods: {
15
+ onClick(e) {
16
+ const btn = e.target.closest('.ui-btn')
17
+ if (!btn || !this.$el.contains(btn)) return
18
+ const value = btn.getAttribute('value') || btn.textContent.trim()
19
+ this.$emit('click', value, e)
20
+ }
21
+ }
22
+ }
23
+ </script>
24
+
25
+ <style src="./button-group.css"></style>
@@ -0,0 +1,30 @@
1
+ .ui-button-group {
2
+ display: inline-flex;
3
+ align-items: stretch;
4
+ }
5
+
6
+ /* Reset radius on all children, re-apply corners to first/last */
7
+ .ui-button-group .ui-btn {
8
+ border-radius: 0;
9
+ }
10
+ .ui-button-group .ui-btn:first-child {
11
+ border-top-left-radius: var(--rounded-xl);
12
+ border-bottom-left-radius: var(--rounded-xl);
13
+ }
14
+ .ui-button-group .ui-btn:last-child {
15
+ border-top-right-radius: var(--rounded-xl);
16
+ border-bottom-right-radius: var(--rounded-xl);
17
+ }
18
+ .ui-button-group .ui-btn:first-child:last-child {
19
+ border-radius: var(--rounded-xl);
20
+ }
21
+
22
+ /* Outlined buttons: collapse shared borders, lift on interaction */
23
+ .ui-button-group .ui-btn--outline:not(:first-child) {
24
+ margin-left: -1px;
25
+ }
26
+ .ui-button-group .ui-btn--outline:hover:not(:disabled),
27
+ .ui-button-group .ui-btn--outline:focus-visible {
28
+ position: relative;
29
+ z-index: 1;
30
+ }
@@ -0,0 +1,55 @@
1
+ <template>
2
+ <span :class="['ui-checkbox', error && 'ui-checkbox--error', disabled && 'ui-checkbox--disabled']">
3
+ <input
4
+ ref="input"
5
+ type="checkbox"
6
+ class="ui-checkbox__input"
7
+ :checked="isChecked"
8
+ :disabled="disabled"
9
+ v-bind="$attrs"
10
+ @change="onChange"
11
+ />
12
+ <span class="ui-checkbox__box" aria-hidden="true">
13
+ <svg v-if="isChecked" xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14" fill="none">
14
+ <path
15
+ d="M11.3055 3.13885C11.5049 2.93952 11.8285 2.93952 12.0279 3.13885C12.2272 3.33818 12.2272 3.66185 12.0279 3.86118L5.61119 10.2778C5.41186 10.4772 5.08819 10.4772 4.88886 10.2778L1.97219 7.36118C1.77286 7.16185 1.77286 6.83818 1.97219 6.63885C2.17152 6.43952 2.49519 6.43952 2.69452 6.63885L5.25002 9.19435L11.3055 3.13885Z"
16
+ fill="white"
17
+ />
18
+ </svg>
19
+ </span>
20
+ </span>
21
+ </template>
22
+
23
+ <script>
24
+ export default {
25
+ name: 'Checkbox',
26
+ inheritAttrs: false,
27
+ model: { prop: 'checked', event: 'change' },
28
+ props: {
29
+ checked: { type: Boolean, default: false },
30
+ modelValue: { type: Boolean, default: undefined },
31
+ error: { type: Boolean, default: false },
32
+ disabled: { type: Boolean, default: false }
33
+ },
34
+ emits: ['change', 'update:modelValue'],
35
+ computed: {
36
+ isChecked() {
37
+ return this.modelValue !== undefined ? this.modelValue : this.checked
38
+ }
39
+ },
40
+ methods: {
41
+ onChange(e) {
42
+ const next = e.target.checked
43
+ this.$emit('change', next, e)
44
+ this.$emit('update:modelValue', next, e)
45
+ this.$nextTick(() => {
46
+ if (this.$refs.input) {
47
+ this.$refs.input.checked = this.isChecked
48
+ }
49
+ })
50
+ }
51
+ }
52
+ }
53
+ </script>
54
+
55
+ <style src="./checkbox.css" scoped></style>
@@ -0,0 +1,86 @@
1
+ .ui-checkbox {
2
+ position: relative;
3
+ display: inline-block;
4
+ flex-shrink: 0;
5
+ width: 16px;
6
+ height: 16px;
7
+ vertical-align: middle;
8
+ }
9
+
10
+ .ui-checkbox__input {
11
+ position: absolute;
12
+ inset: 0;
13
+ width: 100%;
14
+ height: 100%;
15
+ margin: 0;
16
+ padding: 0;
17
+ border: 0;
18
+ cursor: pointer;
19
+ opacity: 0;
20
+ z-index: 1;
21
+ }
22
+
23
+ .ui-checkbox__input:disabled {
24
+ cursor: not-allowed;
25
+ }
26
+
27
+ .ui-checkbox__box {
28
+ position: absolute;
29
+ top: 1px;
30
+ left: 1px;
31
+ width: 16px;
32
+ height: 16px;
33
+ display: inline-flex;
34
+ align-items: center;
35
+ justify-content: center;
36
+ background: var(--input);
37
+ border: 1px solid #d1d1d1;
38
+ border-radius: var(--rounded-md);
39
+ box-shadow: var(--shadow-xs);
40
+ color: var(--inverse-fg);
41
+ pointer-events: none;
42
+ transition:
43
+ background-color 0.12s ease,
44
+ border-color 0.12s ease;
45
+ }
46
+
47
+ .ui-checkbox__input:checked + .ui-checkbox__box,
48
+ .ui-checkbox__input:indeterminate + .ui-checkbox__box {
49
+ background: var(--primary-brand-bg);
50
+ border-color: var(--primary-brand-bg);
51
+ box-shadow: none;
52
+ }
53
+
54
+ .ui-checkbox--error .ui-checkbox__box {
55
+ border-color: var(--destructive-border);
56
+ }
57
+
58
+ .ui-checkbox--error .ui-checkbox__input:checked + .ui-checkbox__box,
59
+ .ui-checkbox--error .ui-checkbox__input:indeterminate + .ui-checkbox__box {
60
+ background: var(--destructive);
61
+ border-color: var(--destructive);
62
+ }
63
+
64
+ .ui-checkbox__input:focus-visible + .ui-checkbox__box {
65
+ box-shadow: 0 0 0 3px var(--focus-ring);
66
+ }
67
+
68
+ .ui-checkbox--error .ui-checkbox__input:focus-visible + .ui-checkbox__box {
69
+ box-shadow: 0 0 0 3px var(--focus-ring-error);
70
+ }
71
+
72
+ .ui-checkbox--disabled {
73
+ opacity: 0.5;
74
+ }
75
+
76
+ .ui-checkbox__check {
77
+ width: 10px;
78
+ height: 10px;
79
+ }
80
+
81
+ .ui-checkbox__dash {
82
+ width: 8px;
83
+ height: 1.5px;
84
+ background: currentColor;
85
+ border-radius: 1px;
86
+ }
@@ -0,0 +1,50 @@
1
+ <template>
2
+ <label :class="['ui-checkbox-group', `ui-checkbox-group--${layout}`, disabled && 'ui-checkbox-group--disabled']">
3
+ <Checkbox
4
+ class="ui-checkbox-group__box"
5
+ :checked="isChecked"
6
+ :error="error"
7
+ :disabled="disabled"
8
+ @change="onChange"
9
+ />
10
+ <span class="ui-checkbox-group__label">
11
+ <slot>{{ label }}</slot>
12
+ </span>
13
+ </label>
14
+ </template>
15
+
16
+ <script>
17
+ import Checkbox from '../checkbox/Checkbox.vue'
18
+
19
+ export default {
20
+ name: 'CheckboxGroup',
21
+ components: { Checkbox },
22
+ model: { prop: 'checked', event: 'change' },
23
+ props: {
24
+ layout: {
25
+ type: String,
26
+ default: 'inline',
27
+ validator: v => ['inline', 'block'].includes(v)
28
+ },
29
+ checked: { type: Boolean, default: false },
30
+ modelValue: { type: Boolean, default: undefined },
31
+ error: { type: Boolean, default: false },
32
+ disabled: { type: Boolean, default: false },
33
+ label: { type: String, default: '' }
34
+ },
35
+ emits: ['change', 'update:modelValue'],
36
+ computed: {
37
+ isChecked() {
38
+ return this.modelValue !== undefined ? this.modelValue : this.checked
39
+ }
40
+ },
41
+ methods: {
42
+ onChange(next) {
43
+ this.$emit('change', next)
44
+ this.$emit('update:modelValue', next)
45
+ }
46
+ }
47
+ }
48
+ </script>
49
+
50
+ <style src="./checkbox-group.css" scoped></style>
@@ -0,0 +1,35 @@
1
+ .ui-checkbox-group {
2
+ display: inline-flex;
3
+ align-items: center;
4
+ gap: var(--spacing-sm);
5
+ height: 24px;
6
+ cursor: pointer;
7
+ font-family: var(--font-family-body);
8
+ font-size: var(--paragraph-small-font-size);
9
+ line-height: var(--paragraph-small-line-height);
10
+ letter-spacing: var(--paragraph-small-letter-spacing);
11
+ color: var(--secondary-fg);
12
+ }
13
+
14
+ .ui-checkbox-group--block {
15
+ display: flex;
16
+ width: 100%;
17
+ }
18
+
19
+ .ui-checkbox-group--block .ui-checkbox-group__label {
20
+ flex: 1 0 0;
21
+ min-width: 0;
22
+ }
23
+
24
+ .ui-checkbox-group--disabled {
25
+ cursor: not-allowed;
26
+ }
27
+
28
+ .ui-checkbox-group__label {
29
+ text-align: left;
30
+ white-space: nowrap;
31
+ }
32
+
33
+ .ui-checkbox-group--block .ui-checkbox-group__label {
34
+ white-space: normal;
35
+ }