@sakoa/ui 0.1.1 → 0.2.0
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.
- package/dist/cli/index.js +8 -0
- package/dist/components/ui/SAlert.d.ts +3 -2
- package/dist/components/ui/SButton.d.ts +6 -5
- package/dist/components/ui/SCheckbox.d.ts +4 -3
- package/dist/components/ui/SDatePicker.d.ts +3 -3
- package/dist/components/ui/SGlassButton.d.ts +6 -5
- package/dist/components/ui/SInput.d.ts +6 -5
- package/dist/components/ui/SSelect.d.ts +5 -4
- package/dist/components/ui/SSwitch.d.ts +6 -5
- package/dist/components/ui/accordion/SAccordionItem.d.ts +7 -6
- package/dist/components/ui/card/SCardHeader.d.ts +4 -3
- package/dist/components/ui/dropdown/SDropdownGroup.d.ts +3 -2
- package/dist/components/ui/dropdown/SDropdownItem.d.ts +7 -6
- package/dist/components/ui/option/SOption.d.ts +3 -2
- package/dist/components/ui/otp/SOTP.d.ts +1 -1
- package/dist/components/ui/pagination/SPagination.d.ts +1 -1
- package/dist/components/ui/progress/SProgress.d.ts +1 -1
- package/dist/components/ui/progress/SProgressRange.d.ts +1 -1
- package/dist/components/ui/radio/SRadio.d.ts +4 -3
- package/dist/components/ui/radio/SRadioGroup.d.ts +1 -1
- package/dist/components/ui/stepper/SStepper.d.ts +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/lib/icon.d.ts +10 -0
- package/dist/saka-ui.css +1 -1
- package/dist/saka-ui.js +5355 -5252
- package/dist/saka-ui.umd.cjs +11 -11
- package/dist/views/docs/CLIView.d.ts +2 -0
- package/dist/views/docs/GettingStartedView.d.ts +2 -0
- package/dist/views/docs/IconsGuideView.d.ts +2 -0
- package/dist/views/docs/UseClickOutsideView.d.ts +9 -9
- package/dist/views/docs/UseHotkeyView.d.ts +10 -10
- package/dist/views/ui/OTPView.d.ts +3 -3
- package/package.json +1 -1
- package/registry/source/components/ui/SAlert.vue +9 -5
- package/registry/source/components/ui/SButton.vue +12 -10
- package/registry/source/components/ui/SCheckbox.vue +4 -2
- package/registry/source/components/ui/SGlassButton.vue +11 -10
- package/registry/source/components/ui/SInput.vue +12 -4
- package/registry/source/components/ui/SSelect.vue +30 -8
- package/registry/source/components/ui/SSwitch.vue +7 -4
- package/registry/source/components/ui/accordion/SAccordionItem.vue +19 -5
- package/registry/source/components/ui/card/SCardHeader.vue +8 -5
- package/registry/source/components/ui/drawer/SDrawerClose.vue +4 -2
- package/registry/source/components/ui/dropdown/SDropdown.vue +11 -7
- package/registry/source/components/ui/dropdown/SDropdownGroup.vue +4 -2
- package/registry/source/components/ui/dropdown/SDropdownItem.vue +10 -7
- package/registry/source/components/ui/option/SOption.vue +9 -2
- package/registry/source/components/ui/radio/SRadio.vue +11 -3
- package/registry/source/components/ui/tabs/STabs.vue +5 -2
|
@@ -9,6 +9,7 @@ defineOptions({ inheritAttrs: false })
|
|
|
9
9
|
|
|
10
10
|
import { inject } from 'vue'
|
|
11
11
|
import { cn } from '../../../lib/utils'
|
|
12
|
+
import { type IconProp, isIconComponent } from '../../../lib/icon'
|
|
12
13
|
import { SDrawerContextKey, type SDrawerContext } from './SDrawer.vue'
|
|
13
14
|
|
|
14
15
|
export interface Props {
|
|
@@ -19,7 +20,7 @@ export interface Props {
|
|
|
19
20
|
/** Visual variant */
|
|
20
21
|
variant?: 'default' | 'ghost' | 'subtle'
|
|
21
22
|
/** Icon to display */
|
|
22
|
-
icon?:
|
|
23
|
+
icon?: IconProp
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
const props = withDefaults(defineProps<Props>(), {
|
|
@@ -59,6 +60,7 @@ const variantClasses = {
|
|
|
59
60
|
aria-label="Close drawer"
|
|
60
61
|
@click="handleClose"
|
|
61
62
|
>
|
|
62
|
-
<
|
|
63
|
+
<component v-if="isIconComponent(icon)" :is="icon" class="text-xl" />
|
|
64
|
+
<span v-else :class="`mdi mdi-${icon} text-xl`" />
|
|
63
65
|
</button>
|
|
64
66
|
</template>
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* A highly customizable dropdown component for menus, actions, and navigation
|
|
5
5
|
*/
|
|
6
6
|
import { type InjectionKey, type Ref } from 'vue'
|
|
7
|
+
import { type IconProp, isIconComponent } from '../../../lib/icon'
|
|
7
8
|
|
|
8
9
|
// Types
|
|
9
10
|
export type DropdownTrigger = 'click' | 'hover' | 'context' | 'manual'
|
|
@@ -19,8 +20,8 @@ export type DropdownAnimation = 'fade' | 'slide' | 'scale' | 'reveal'
|
|
|
19
20
|
export interface DropdownMenuItem {
|
|
20
21
|
key: string
|
|
21
22
|
label: string
|
|
22
|
-
icon?:
|
|
23
|
-
trailingIcon?:
|
|
23
|
+
icon?: IconProp
|
|
24
|
+
trailingIcon?: IconProp
|
|
24
25
|
description?: string
|
|
25
26
|
shortcut?: string
|
|
26
27
|
disabled?: boolean
|
|
@@ -98,7 +99,7 @@ export interface Props {
|
|
|
98
99
|
/** Trigger button text */
|
|
99
100
|
label?: string
|
|
100
101
|
/** Trigger button icon */
|
|
101
|
-
icon?:
|
|
102
|
+
icon?: IconProp
|
|
102
103
|
/** Hide the dropdown arrow on trigger */
|
|
103
104
|
hideArrow?: boolean
|
|
104
105
|
}
|
|
@@ -589,7 +590,8 @@ defineExpose({
|
|
|
589
590
|
]"
|
|
590
591
|
:disabled="disabled"
|
|
591
592
|
>
|
|
592
|
-
<
|
|
593
|
+
<component v-if="icon && isIconComponent(icon)" :is="icon" :class="[sizeConfig.icon]" />
|
|
594
|
+
<span v-else-if="icon" :class="['mdi', `mdi-${icon}`, sizeConfig.icon]" />
|
|
593
595
|
<span v-if="label">{{ label }}</span>
|
|
594
596
|
<span
|
|
595
597
|
v-if="!hideArrow"
|
|
@@ -704,7 +706,8 @@ defineExpose({
|
|
|
704
706
|
/>
|
|
705
707
|
|
|
706
708
|
<!-- Leading icon -->
|
|
707
|
-
<
|
|
709
|
+
<component v-else-if="item.icon && isIconComponent(item.icon)" :is="item.icon" :class="[sizeConfig.icon, 'mr-2.5', item.danger ? '' : 'text-muted-foreground']" />
|
|
710
|
+
<span
|
|
708
711
|
v-else-if="item.icon"
|
|
709
712
|
:class="['mdi', `mdi-${item.icon}`, sizeConfig.icon, 'mr-2.5', item.danger ? '' : 'text-muted-foreground']"
|
|
710
713
|
/>
|
|
@@ -732,8 +735,9 @@ defineExpose({
|
|
|
732
735
|
</kbd>
|
|
733
736
|
|
|
734
737
|
<!-- Trailing icon -->
|
|
735
|
-
<
|
|
736
|
-
|
|
738
|
+
<component v-if="item.trailingIcon && isIconComponent(item.trailingIcon)" :is="item.trailingIcon" :class="[sizeConfig.icon, 'text-muted-foreground']" />
|
|
739
|
+
<span
|
|
740
|
+
v-else-if="item.trailingIcon"
|
|
737
741
|
:class="['mdi', `mdi-${item.trailingIcon}`, sizeConfig.icon, 'text-muted-foreground']"
|
|
738
742
|
/>
|
|
739
743
|
|
|
@@ -3,13 +3,14 @@ defineOptions({ inheritAttrs: false })
|
|
|
3
3
|
|
|
4
4
|
import { inject, computed } from 'vue'
|
|
5
5
|
import { cn } from '../../../lib/utils'
|
|
6
|
+
import { type IconProp, isIconComponent } from '../../../lib/icon'
|
|
6
7
|
import { SDropdownContextKey, type SDropdownContext } from './SDropdown.vue'
|
|
7
8
|
|
|
8
9
|
export interface Props {
|
|
9
10
|
/** Group header label */
|
|
10
11
|
label: string
|
|
11
12
|
/** Icon for the header */
|
|
12
|
-
icon?:
|
|
13
|
+
icon?: IconProp
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
const props = withDefaults(defineProps<Props>(), {
|
|
@@ -33,7 +34,8 @@ const sizeConfig = computed(() => ({
|
|
|
33
34
|
class="font-semibold uppercase tracking-wider text-muted-foreground flex items-center gap-2 sticky top-0 bg-background/95 backdrop-blur-sm"
|
|
34
35
|
:class="sizeConfig"
|
|
35
36
|
>
|
|
36
|
-
<
|
|
37
|
+
<component v-if="icon && isIconComponent(icon)" :is="icon" class="text-xs" />
|
|
38
|
+
<span v-else-if="icon" :class="['mdi', `mdi-${icon}`, 'text-xs']" />
|
|
37
39
|
<span>{{ label }}</span>
|
|
38
40
|
</div>
|
|
39
41
|
|
|
@@ -3,6 +3,7 @@ defineOptions({ inheritAttrs: false })
|
|
|
3
3
|
|
|
4
4
|
import { inject, ref, computed, onMounted, onBeforeUnmount } from 'vue'
|
|
5
5
|
import { cn } from '../../../lib/utils'
|
|
6
|
+
import { type IconProp, isIconComponent } from '../../../lib/icon'
|
|
6
7
|
import { SDropdownContextKey, type SDropdownContext } from './SDropdown.vue'
|
|
7
8
|
|
|
8
9
|
export interface Props {
|
|
@@ -10,10 +11,10 @@ export interface Props {
|
|
|
10
11
|
itemKey: string
|
|
11
12
|
/** Item label text */
|
|
12
13
|
label?: string
|
|
13
|
-
/** Leading icon (MDI icon name) */
|
|
14
|
-
icon?:
|
|
15
|
-
/** Trailing icon */
|
|
16
|
-
trailingIcon?:
|
|
14
|
+
/** Leading icon (MDI icon name or Vue component) */
|
|
15
|
+
icon?: IconProp
|
|
16
|
+
/** Trailing icon (MDI icon name or Vue component) */
|
|
17
|
+
trailingIcon?: IconProp
|
|
17
18
|
/** Description text below label */
|
|
18
19
|
description?: string
|
|
19
20
|
/** Keyboard shortcut display */
|
|
@@ -130,7 +131,8 @@ const handleClick = (event: MouseEvent) => {
|
|
|
130
131
|
/>
|
|
131
132
|
|
|
132
133
|
<!-- Leading icon -->
|
|
133
|
-
<
|
|
134
|
+
<component v-else-if="icon && isIconComponent(icon)" :is="icon" :class="[sizeConfig.icon, 'mr-2.5', danger ? '' : 'text-muted-foreground group-hover:text-foreground']" />
|
|
135
|
+
<span
|
|
134
136
|
v-else-if="icon"
|
|
135
137
|
:class="['mdi', `mdi-${icon}`, sizeConfig.icon, 'mr-2.5', danger ? '' : 'text-muted-foreground group-hover:text-foreground']"
|
|
136
138
|
/>
|
|
@@ -160,8 +162,9 @@ const handleClick = (event: MouseEvent) => {
|
|
|
160
162
|
</kbd>
|
|
161
163
|
|
|
162
164
|
<!-- Trailing icon -->
|
|
163
|
-
<
|
|
164
|
-
|
|
165
|
+
<component v-if="trailingIcon && isIconComponent(trailingIcon)" :is="trailingIcon" :class="[sizeConfig.icon, 'text-muted-foreground']" />
|
|
166
|
+
<span
|
|
167
|
+
v-else-if="trailingIcon"
|
|
165
168
|
:class="['mdi', `mdi-${trailingIcon}`, sizeConfig.icon, 'text-muted-foreground']"
|
|
166
169
|
/>
|
|
167
170
|
|
|
@@ -3,12 +3,13 @@ defineOptions({ inheritAttrs: false })
|
|
|
3
3
|
|
|
4
4
|
import { inject, computed, type CSSProperties } from 'vue'
|
|
5
5
|
import { cn } from '../../../lib/utils'
|
|
6
|
+
import { type IconProp, isIconComponent } from '../../../lib/icon'
|
|
6
7
|
|
|
7
8
|
export interface Props {
|
|
8
9
|
value: any
|
|
9
10
|
label?: string
|
|
10
11
|
disabled?: boolean
|
|
11
|
-
icon?:
|
|
12
|
+
icon?: IconProp
|
|
12
13
|
description?: string
|
|
13
14
|
color?: string
|
|
14
15
|
}
|
|
@@ -132,8 +133,14 @@ const bgClass = computed(() => {
|
|
|
132
133
|
/>
|
|
133
134
|
|
|
134
135
|
<!-- Icon -->
|
|
136
|
+
<component
|
|
137
|
+
v-if="icon && isIconComponent(icon)"
|
|
138
|
+
:is="icon"
|
|
139
|
+
:class="cn('relative z-10 shrink-0', sizeConfig.icon, isSelected && !hasCustomColor ? 'text-primary' : '')"
|
|
140
|
+
:style="isSelected && hasCustomColor ? { color: resolvedColor } : {}"
|
|
141
|
+
/>
|
|
135
142
|
<span
|
|
136
|
-
v-if="icon"
|
|
143
|
+
v-else-if="icon"
|
|
137
144
|
:class="cn('relative z-10 shrink-0 mdi', `mdi-${icon}`, sizeConfig.icon, isSelected && !hasCustomColor ? 'text-primary' : '')"
|
|
138
145
|
:style="isSelected && hasCustomColor ? { color: resolvedColor } : {}"
|
|
139
146
|
/>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { computed, ref, inject, type CSSProperties } from 'vue'
|
|
3
3
|
import { cn } from '../../../lib/utils'
|
|
4
|
+
import { type IconProp, isIconComponent } from '../../../lib/icon'
|
|
4
5
|
|
|
5
6
|
defineOptions({ inheritAttrs: false })
|
|
6
7
|
|
|
@@ -14,7 +15,7 @@ export interface Props {
|
|
|
14
15
|
label?: string
|
|
15
16
|
labelPosition?: 'left' | 'right'
|
|
16
17
|
variant?: 'default' | 'filled' | 'outlined' | 'button'
|
|
17
|
-
icon?:
|
|
18
|
+
icon?: IconProp
|
|
18
19
|
required?: boolean
|
|
19
20
|
name?: string
|
|
20
21
|
error?: string
|
|
@@ -195,8 +196,9 @@ const buttonStyle = computed<CSSProperties>(() => {
|
|
|
195
196
|
></span>
|
|
196
197
|
|
|
197
198
|
<!-- Icon -->
|
|
199
|
+
<component v-if="icon && !loading && isIconComponent(icon)" :is="icon" class="mr-2" />
|
|
198
200
|
<span
|
|
199
|
-
v-if="icon && !loading"
|
|
201
|
+
v-else-if="icon && !loading"
|
|
200
202
|
:class="['mdi', `mdi-${icon}`, 'mr-2']"
|
|
201
203
|
></span>
|
|
202
204
|
|
|
@@ -296,8 +298,14 @@ const buttonStyle = computed<CSSProperties>(() => {
|
|
|
296
298
|
:class="currentVariant === 'filled' ? (hasCustomColor ? 'text-white' : 'text-primary-foreground') : ''"
|
|
297
299
|
>
|
|
298
300
|
<slot name="icon">
|
|
301
|
+
<component
|
|
302
|
+
v-if="icon && isIconComponent(icon)"
|
|
303
|
+
:is="icon"
|
|
304
|
+
:class="cn(sizeConfig.icon, currentVariant !== 'filled' && !hasCustomColor ? 'text-primary' : '')"
|
|
305
|
+
:style="currentVariant !== 'filled' && hasCustomColor ? { color: currentColor } : {}"
|
|
306
|
+
/>
|
|
299
307
|
<span
|
|
300
|
-
v-if="icon"
|
|
308
|
+
v-else-if="icon"
|
|
301
309
|
:class="cn('mdi', `mdi-${icon}`, sizeConfig.icon, currentVariant !== 'filled' && !hasCustomColor ? 'text-primary' : '')"
|
|
302
310
|
:style="currentVariant !== 'filled' && hasCustomColor ? { color: currentColor } : {}"
|
|
303
311
|
/>
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Supports both simple (STabPane) and compound (STabsList + STabsTrigger + STabsContent) APIs
|
|
5
5
|
*/
|
|
6
6
|
import { type InjectionKey, type Ref } from 'vue'
|
|
7
|
+
import type { IconProp } from '../../../lib/icon'
|
|
7
8
|
|
|
8
9
|
// Types - exported for external use
|
|
9
10
|
export type TabType = 'line' | 'card' | 'segment' | 'bar' | 'chip'
|
|
@@ -14,7 +15,7 @@ export type TabJustify = 'flex-start' | 'center' | 'flex-end' | 'space-between'
|
|
|
14
15
|
export interface TabPaneInfo {
|
|
15
16
|
name: string | number
|
|
16
17
|
tab: string
|
|
17
|
-
icon?:
|
|
18
|
+
icon?: IconProp
|
|
18
19
|
disabled?: boolean
|
|
19
20
|
closable?: boolean
|
|
20
21
|
tabClass?: string
|
|
@@ -44,6 +45,7 @@ defineOptions({ inheritAttrs: false })
|
|
|
44
45
|
|
|
45
46
|
import { provide, ref, computed, watch, nextTick, onMounted, useSlots } from 'vue'
|
|
46
47
|
import { cn } from '../../../lib/utils'
|
|
48
|
+
import { isIconComponent } from '../../../lib/icon'
|
|
47
49
|
|
|
48
50
|
// Props
|
|
49
51
|
export interface Props {
|
|
@@ -416,8 +418,9 @@ provide(STabsContextKey, {
|
|
|
416
418
|
:close="() => emit('close', pane.name)"
|
|
417
419
|
>
|
|
418
420
|
<!-- Icon -->
|
|
421
|
+
<component v-if="pane.icon && isIconComponent(pane.icon)" :is="pane.icon" :class="[{ 'scale-110': activeTab === pane.name }]" />
|
|
419
422
|
<span
|
|
420
|
-
v-if="pane.icon"
|
|
423
|
+
v-else-if="pane.icon"
|
|
421
424
|
class="mdi transition-transform duration-300"
|
|
422
425
|
:class="[`mdi-${pane.icon}`, { 'scale-110': activeTab === pane.name }]"
|
|
423
426
|
/>
|