urkit-ui 0.1.5

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 (83) hide show
  1. package/README.md +322 -0
  2. package/dist/module.cjs +75 -0
  3. package/dist/module.d.cts +46 -0
  4. package/dist/module.d.mts +46 -0
  5. package/dist/module.d.ts +46 -0
  6. package/dist/module.json +12 -0
  7. package/dist/module.mjs +72 -0
  8. package/dist/runtime/assets/css/buttons.css +1 -0
  9. package/dist/runtime/assets/css/colors.css +1 -0
  10. package/dist/runtime/assets/css/form-fields.css +1 -0
  11. package/dist/runtime/assets/css/global.css +1 -0
  12. package/dist/runtime/components/Button.d.vue.ts +87 -0
  13. package/dist/runtime/components/Button.vue +147 -0
  14. package/dist/runtime/components/Button.vue.d.ts +87 -0
  15. package/dist/runtime/components/Icon.d.vue.ts +9 -0
  16. package/dist/runtime/components/Icon.vue +71 -0
  17. package/dist/runtime/components/Icon.vue.d.ts +9 -0
  18. package/dist/runtime/components/Input.d.vue.ts +129 -0
  19. package/dist/runtime/components/Input.vue +342 -0
  20. package/dist/runtime/components/Input.vue.d.ts +129 -0
  21. package/dist/runtime/composables/useIcon.d.ts +5 -0
  22. package/dist/runtime/composables/useIcon.js +71 -0
  23. package/dist/runtime/plugin.d.ts +2 -0
  24. package/dist/runtime/plugin.js +4 -0
  25. package/dist/runtime/public/assets/icons/arrow-down.svg +10 -0
  26. package/dist/runtime/public/assets/icons/collapse.svg +6 -0
  27. package/dist/runtime/public/assets/icons/color.svg +1 -0
  28. package/dist/runtime/public/assets/icons/copied.svg +3 -0
  29. package/dist/runtime/public/assets/icons/copy.svg +10 -0
  30. package/dist/runtime/public/assets/icons/figma.svg +1 -0
  31. package/dist/runtime/public/assets/icons/heart.svg +3 -0
  32. package/dist/runtime/public/assets/icons/hide.svg +8 -0
  33. package/dist/runtime/public/assets/icons/icons-icon.svg +10 -0
  34. package/dist/runtime/public/assets/icons/installation.svg +1 -0
  35. package/dist/runtime/public/assets/icons/introduction.svg +1 -0
  36. package/dist/runtime/public/assets/icons/loader-icon.svg +6 -0
  37. package/dist/runtime/public/assets/icons/profile.svg +1 -0
  38. package/dist/runtime/public/assets/icons/radiuss.svg +4 -0
  39. package/dist/runtime/public/assets/icons/search.svg +1 -0
  40. package/dist/runtime/public/assets/icons/show.svg +4 -0
  41. package/dist/runtime/public/assets/icons/star.svg +3 -0
  42. package/dist/runtime/public/assets/icons/toast-close.svg +3 -0
  43. package/dist/runtime/public/assets/icons/toast-error.svg +4 -0
  44. package/dist/runtime/public/assets/icons/toast-info.svg +5 -0
  45. package/dist/runtime/public/assets/icons/toast-success.svg +4 -0
  46. package/dist/runtime/public/assets/icons/toast-warning.svg +5 -0
  47. package/dist/runtime/public/assets/icons/typo.svg +1 -0
  48. package/dist/runtime/public/assets/logos/urkit-logo-blue.svg +53 -0
  49. package/dist/runtime/public/assets/logos/urkit-logo-cyan.svg +53 -0
  50. package/dist/runtime/public/assets/logos/urkit-logo-green.svg +53 -0
  51. package/dist/runtime/public/assets/logos/urkit-logo-purple.svg +53 -0
  52. package/dist/runtime/public/assets/logos/urkit-logo.svg +19 -0
  53. package/dist/runtime/server/tsconfig.json +3 -0
  54. package/dist/types.d.mts +3 -0
  55. package/package.json +70 -0
  56. package/src/runtime/public/assets/icons/arrow-down.svg +10 -0
  57. package/src/runtime/public/assets/icons/collapse.svg +6 -0
  58. package/src/runtime/public/assets/icons/color.svg +1 -0
  59. package/src/runtime/public/assets/icons/copied.svg +3 -0
  60. package/src/runtime/public/assets/icons/copy.svg +10 -0
  61. package/src/runtime/public/assets/icons/figma.svg +1 -0
  62. package/src/runtime/public/assets/icons/heart.svg +3 -0
  63. package/src/runtime/public/assets/icons/hide.svg +8 -0
  64. package/src/runtime/public/assets/icons/icons-icon.svg +10 -0
  65. package/src/runtime/public/assets/icons/installation.svg +1 -0
  66. package/src/runtime/public/assets/icons/introduction.svg +1 -0
  67. package/src/runtime/public/assets/icons/loader-icon.svg +6 -0
  68. package/src/runtime/public/assets/icons/profile.svg +1 -0
  69. package/src/runtime/public/assets/icons/radiuss.svg +4 -0
  70. package/src/runtime/public/assets/icons/search.svg +1 -0
  71. package/src/runtime/public/assets/icons/show.svg +4 -0
  72. package/src/runtime/public/assets/icons/star.svg +3 -0
  73. package/src/runtime/public/assets/icons/toast-close.svg +3 -0
  74. package/src/runtime/public/assets/icons/toast-error.svg +4 -0
  75. package/src/runtime/public/assets/icons/toast-info.svg +5 -0
  76. package/src/runtime/public/assets/icons/toast-success.svg +4 -0
  77. package/src/runtime/public/assets/icons/toast-warning.svg +5 -0
  78. package/src/runtime/public/assets/icons/typo.svg +1 -0
  79. package/src/runtime/public/assets/logos/urkit-logo-blue.svg +53 -0
  80. package/src/runtime/public/assets/logos/urkit-logo-cyan.svg +53 -0
  81. package/src/runtime/public/assets/logos/urkit-logo-green.svg +53 -0
  82. package/src/runtime/public/assets/logos/urkit-logo-purple.svg +53 -0
  83. package/src/runtime/public/assets/logos/urkit-logo.svg +19 -0
@@ -0,0 +1,87 @@
1
+ import type { RouteLocationRaw } from 'vue-router';
2
+ /**
3
+ * Button variant types
4
+ */
5
+ type ButtonVariant = 'primary' | 'error' | 'success' | 'neutral';
6
+ /**
7
+ * Button size types
8
+ */
9
+ type ButtonSize = 'sm' | 'md' | 'lg' | 'xlg';
10
+ /**
11
+ * Icon position types
12
+ */
13
+ type IconPosition = 'left' | 'right';
14
+ /**
15
+ * Icon collection types
16
+ */
17
+ type IconCollection = 'custom' | 'currencies' | 'icons';
18
+ /**
19
+ * Button mode types
20
+ */
21
+ type ButtonMode = 'filled' | 'stroke' | 'lighter' | 'ghost';
22
+ /**
23
+ * Button radius types
24
+ */
25
+ type ButtonRadiusType = 'none' | 'soft' | 'medium' | 'pill';
26
+ /**
27
+ * Button component props interface
28
+ */
29
+ interface ButtonProps {
30
+ /** Button style variant */
31
+ variant?: ButtonVariant;
32
+ /** Navigation target (for NuxtLink) */
33
+ to?: string | RouteLocationRaw;
34
+ /** Button size */
35
+ size?: ButtonSize;
36
+ /** Icon name */
37
+ icon?: string;
38
+ /** Icon position relative to label */
39
+ iconPosition?: IconPosition;
40
+ /** Icon collection namespace */
41
+ iconCollection?: IconCollection;
42
+ /** Button label text */
43
+ label?: string;
44
+ /** Loading state label */
45
+ loadingLabel?: string;
46
+ /** Whether button has rounded corners */
47
+ rounded?: boolean;
48
+ /** Whether button is in loading state */
49
+ loading?: boolean;
50
+ /** External link href (renders as anchor) */
51
+ href?: string | null;
52
+ /** Whether button is disabled */
53
+ disabled?: boolean;
54
+ /** Button type attribute */
55
+ type?: 'button' | 'submit' | 'reset';
56
+ /** Button mode */
57
+ mode?: ButtonMode;
58
+ /** Radius type with size-aware values */
59
+ radiusType?: ButtonRadiusType;
60
+ }
61
+ declare var __VLS_19: {};
62
+ type __VLS_Slots = {} & {
63
+ default?: (props: typeof __VLS_19) => any;
64
+ };
65
+ declare const __VLS_component: import("vue").DefineComponent<ButtonProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
66
+ click: (event: MouseEvent) => any;
67
+ }, string, import("vue").PublicProps, Readonly<ButtonProps> & Readonly<{
68
+ onClick?: ((event: MouseEvent) => any) | undefined;
69
+ }>, {
70
+ size: ButtonSize;
71
+ type: "button" | "submit" | "reset";
72
+ variant: ButtonVariant;
73
+ iconPosition: IconPosition;
74
+ iconCollection: IconCollection;
75
+ rounded: boolean;
76
+ loading: boolean;
77
+ disabled: boolean;
78
+ mode: ButtonMode;
79
+ radiusType: ButtonRadiusType;
80
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
81
+ declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
82
+ export default _default;
83
+ type __VLS_WithSlots<T, S> = T & {
84
+ new (): {
85
+ $slots: S;
86
+ };
87
+ };
@@ -0,0 +1,147 @@
1
+ <template>
2
+ <component
3
+ :is="componentTag"
4
+ :href="isLink ? href : void 0"
5
+ :to="isNuxtLink ? to : void 0"
6
+ :disabled="isDisabled"
7
+ :type="buttonType"
8
+ :class="buttonClasses"
9
+ :aria-label="ariaLabel"
10
+ :aria-disabled="isDisabled"
11
+ :aria-busy="loading"
12
+ @click="handleClick"
13
+ >
14
+ <!-- Loading State -->
15
+ <span v-if="loading && !loadingLabel" class="form-button__loading" aria-hidden="true">
16
+ <Icon name="icons:loader-icon" size="20" class="form-button__loading-icon" alt="" />
17
+ </span>
18
+
19
+ <!-- Left Icon -->
20
+ <span
21
+ v-if="icon && iconPosition === 'left' && !loading"
22
+ class="form-button__icon form-button__icon--left"
23
+ aria-hidden="true"
24
+ >
25
+ <Icon :name="iconName" size="20" alt="" />
26
+ </span>
27
+
28
+ <!-- Loading with Label -->
29
+ <div v-if="loading && loadingLabel" class="form-button__loading-wrapper">
30
+ <span class="form-button__loading" aria-hidden="true">
31
+ <Icon name="icons:loader-icon" size="16" class="form-button__loading-icon" alt="" />
32
+ </span>
33
+ <span class="form-button__label">{{ loadingLabel }}</span>
34
+ </div>
35
+
36
+ <!-- Button Label -->
37
+ <span v-if="label && !loading" class="form-button__label">
38
+ {{ label }}
39
+ </span>
40
+
41
+ <!-- Default Slot -->
42
+ <slot v-if="!label && !loading" />
43
+
44
+ <!-- Right Icon -->
45
+ <span
46
+ v-if="icon && iconPosition === 'right' && !loading"
47
+ class="form-button__icon form-button__icon--right"
48
+ aria-hidden="true"
49
+ >
50
+ <Icon :name="iconName" size="20" alt="" />
51
+ </span>
52
+ </component>
53
+ </template>
54
+
55
+ <script setup>
56
+ import { computed, useAttrs } from "vue";
57
+ import Icon from "./Icon.vue";
58
+ const props = defineProps({
59
+ variant: { type: String, required: false, default: "primary" },
60
+ to: { type: null, required: false },
61
+ size: { type: String, required: false, default: "md" },
62
+ icon: { type: String, required: false },
63
+ iconPosition: { type: String, required: false, default: "left" },
64
+ iconCollection: { type: String, required: false, default: "icons" },
65
+ label: { type: String, required: false },
66
+ loadingLabel: { type: String, required: false },
67
+ rounded: { type: Boolean, required: false, default: false },
68
+ loading: { type: Boolean, required: false, default: false },
69
+ href: { type: [String, null], required: false },
70
+ disabled: { type: Boolean, required: false, default: false },
71
+ type: { type: String, required: false, default: "button" },
72
+ mode: { type: String, required: false, default: "filled" },
73
+ radiusType: { type: String, required: false, default: "soft" }
74
+ });
75
+ const emit = defineEmits(["click"]);
76
+ const attrs = useAttrs();
77
+ const componentTag = computed(() => {
78
+ if (props.href) return "a";
79
+ if (props.to) return "NuxtLink";
80
+ return "button";
81
+ });
82
+ const isLink = computed(() => {
83
+ return Boolean(props.href);
84
+ });
85
+ const isNuxtLink = computed(() => {
86
+ return Boolean(props.to);
87
+ });
88
+ const isDisabled = computed(() => {
89
+ return props.disabled || props.loading;
90
+ });
91
+ const buttonType = computed(() => {
92
+ return componentTag.value === "button" ? props.type : void 0;
93
+ });
94
+ const iconName = computed(() => {
95
+ if (!props.icon) return "";
96
+ return `${props.iconCollection}:${props.icon}`;
97
+ });
98
+ const ariaLabel = computed(() => {
99
+ if (props.loading && props.loadingLabel) {
100
+ return `Loading: ${props.loadingLabel}`;
101
+ }
102
+ if (props.loading) {
103
+ return "Loading";
104
+ }
105
+ return props.label || "";
106
+ });
107
+ const buttonClasses = computed(() => {
108
+ const classes = [
109
+ "form-button",
110
+ `form-button--${props.variant}`,
111
+ `form-button--${props.size}`,
112
+ `form-button--mode-${props.mode}`
113
+ ];
114
+ if (props.radiusType) {
115
+ classes.push(`form-button--radius-${props.radiusType}`);
116
+ }
117
+ if (props.loading) {
118
+ classes.push("form-button--loading");
119
+ }
120
+ if (props.disabled) {
121
+ classes.push("form-button--disabled");
122
+ }
123
+ if (props.rounded) {
124
+ classes.push("form-button--rounded");
125
+ }
126
+ if (isLink.value) {
127
+ classes.push("form-button--link");
128
+ }
129
+ if (attrs.class) {
130
+ if (Array.isArray(attrs.class)) {
131
+ classes.push(...attrs.class);
132
+ } else {
133
+ classes.push(attrs.class);
134
+ }
135
+ }
136
+ return classes;
137
+ });
138
+ const handleClick = (event) => {
139
+ if (!isDisabled.value) {
140
+ emit("click", event);
141
+ }
142
+ };
143
+ </script>
144
+
145
+ <style scoped>
146
+ .form-button{align-items:center;background:none;border:none;border-radius:var(--border-radius-2,8px);cursor:pointer;display:inline-flex;font-family:InterFull,sans-serif;font-size:14px;font-weight:500;gap:8px;justify-content:center;outline:none;padding:0 16px;text-decoration:none;transition:all .2s ease;-webkit-user-select:none;-moz-user-select:none;user-select:none;white-space:nowrap}.form-button:focus-visible{outline:1px solid var(--primary-500)}.form-button__label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.form-button__icon,.form-button__loading{align-items:center;display:flex;flex-shrink:0;justify-content:center}.form-button__loading-wrapper{align-items:center;display:flex;gap:6px}.form-button__loading-icon{animation:buttonSpinner 1s linear infinite}@keyframes buttonSpinner{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.form-button--sm{font-size:12px;gap:6px;height:32px;padding:0 12px}.form-button--md{font-size:13px;gap:6px;height:36px;padding:0 14px}.form-button--lg{font-size:14px;gap:8px;height:40px;padding:0 16px}.form-button--xlg{font-size:15px;gap:8px;height:44px;padding:0 18px}.form-button--primary.form-button--mode-filled{background:var(--primary-600);border:none;color:var(--white)}.form-button--primary.form-button--mode-filled:hover:not(:disabled){background:var(--primary-700)}.form-button--primary.form-button--mode-filled:active:not(:disabled){background:var(--primary-800)}.form-button--primary.form-button--mode-stroke{background:transparent;border:1px solid var(--primary-600);color:var(--primary-600)}.form-button--primary.form-button--mode-stroke:hover:not(:disabled){background:var(--primary-50)}.form-button--primary.form-button--mode-stroke:active:not(:disabled){background:var(--primary-100)}.form-button--primary.form-button--mode-lighter{background:var(--primary-50);border:none;color:var(--primary-600)}.form-button--primary.form-button--mode-ghost{background:none;border:none;color:var(--primary-600)}.form-button--primary.form-button--mode-ghost:hover:not(:disabled){background:var(--primary-50)}.form-button--primary.form-button--mode-ghost:active:not(:disabled){background:var(--primary-100)}.form-button--error.form-button--mode-filled{background:var(--error);border:none;color:var(--white)}.form-button--error.form-button--mode-filled:hover:not(:disabled){background:var(--error-dark)}.form-button--error.form-button--mode-filled:active:not(:disabled){background:var(--error-contrast)}.form-button--error.form-button--mode-stroke{background:transparent;border:1px solid var(--error);color:var(--error)}.form-button--error.form-button--mode-stroke:hover:not(:disabled){background:var(--error-light);border-color:var(--error-dark);color:var(--error-dark)}.form-button--error.form-button--mode-stroke:active:not(:disabled){background:var(--error-light);border-color:var(--error-contrast);color:var(--error-contrast)}.form-button--error.form-button--mode-lighter{background:var(--error-light);border:none;color:var(--error)}.form-button--error.form-button--mode-lighter:hover:not(:disabled){background:#ffd6d6;color:var(--error-dark)}.form-button--error.form-button--mode-lighter:active:not(:disabled){background:#ffebeb;color:var(--error-contrast)}.form-button--error.form-button--mode-ghost{background:none;border:none;color:var(--error)}.form-button--error.form-button--mode-ghost:hover:not(:disabled){background:var(--error-light);color:var(--error-dark)}.form-button--error.form-button--mode-ghost:active:not(:disabled){background:#ffebeb;color:var(--error-contrast)}.form-button--success.form-button--mode-filled{background:var(--success);border:none;color:var(--white)}.form-button--success.form-button--mode-filled:hover:not(:disabled){background:var(--success-dark)}.form-button--success.form-button--mode-filled:active:not(:disabled){background:var(--success-contrast)}.form-button--success.form-button--mode-stroke{background:transparent;border:1px solid var(--success);color:var(--success)}.form-button--success.form-button--mode-stroke:hover:not(:disabled){background:var(--success-light);border-color:var(--success-dark);color:var(--success-dark)}.form-button--success.form-button--mode-stroke:active:not(:disabled){background:var(--success-light);border-color:var(--success-contrast);color:var(--success-contrast)}.form-button--success.form-button--mode-lighter{background:var(--success-light);border:none;color:var(--success)}.form-button--success.form-button--mode-lighter:hover:not(:disabled){background:#d2fbe7;color:var(--success-dark)}.form-button--success.form-button--mode-lighter:active:not(:disabled){background:#eafcf3;color:var(--success-contrast)}.form-button--success.form-button--mode-ghost{background:none;border:none;color:var(--success)}.form-button--success.form-button--mode-ghost:hover:not(:disabled){background:var(--success-light);color:var(--success-dark)}.form-button--success.form-button--mode-ghost:active:not(:disabled){background:#eafcf3;color:var(--success-contrast)}.form-button--white.form-button--mode-filled{background:var(--white);border:1px solid var(--neutral-4);color:var(--neutral-12)}.form-button--white.form-button--mode-filled:hover:not(:disabled){background:var(--neutral-2)}.form-button--white.form-button--mode-filled:active:not(:disabled){background:var(--neutral-3)}.form-button--white.form-button--mode-stroke{background:transparent;border:1px solid var(--neutral-4);color:var(--neutral-12)}.form-button--white.form-button--mode-stroke:hover:not(:disabled){background:var(--neutral-1);border-color:var(--neutral-6);color:var(--neutral-12)}.form-button--white.form-button--mode-stroke:active:not(:disabled){background:var(--neutral-2);border-color:var(--neutral-7);color:var(--neutral-12)}.form-button--white.form-button--mode-lighter{background:var(--neutral-3);border:none;color:var(--neutral-12)}.form-button--white.form-button--mode-lighter:hover:not(:disabled){background:var(--neutral-2);color:var(--neutral-12)}.form-button--white.form-button--mode-lighter:active:not(:disabled){background:var(--neutral-1);color:var(--neutral-12)}.form-button--white.form-button--mode-ghost{background:none;border:none;color:var(--neutral-12)}.form-button--white.form-button--mode-ghost:hover:not(:disabled){background:var(--neutral-2);color:var(--neutral-12)}.form-button--white.form-button--mode-ghost:active:not(:disabled){background:var(--neutral-3);color:var(--neutral-12)}.form-button--neutral.form-button--mode-stroke:hover:not(:disabled){border-color:var(--neutral-6)}.form-button--loading{cursor:not-allowed;pointer-events:none}.form-button--disabled,.form-button:disabled{background-color:var(--neutral-9)!important;border-color:var(--neutral-10)!important;box-shadow:none!important;color:var(--neutral-6)!important;cursor:not-allowed!important;pointer-events:none!important;transform:none!important}.form-button--rounded{border-radius:9999px}.form-button--link{display:inline-flex}@media screen and (max-width:768px){.form-button{min-height:44px}.form-button--sm{height:36px}.form-button--md{height:40px}}.form-button--mode-stroke{background:transparent;border:1px solid var(--primary-600);color:var(--primary-600)}.form-button--mode-lighter{background:var(--primary-100);border:none;color:var(--primary-600)}.form-button--mode-ghost{background:none;border:none;box-shadow:none;color:var(--primary-600)}.form-button--primary.form-button--mode-stroke:hover:not(:disabled){background:rgba(44,98,255,.06);border-color:var(--primary-700);color:var(--primary-700)}.form-button--primary.form-button--mode-stroke:active:not(:disabled){background:rgba(44,98,255,.12);border-color:var(--primary-800);color:var(--primary-800)}.form-button--primary.form-button--mode-lighter:hover:not(:disabled){background:var(--primary-200);color:var(--primary-700)}.form-button--primary.form-button--mode-lighter:active:not(:disabled){background:var(--primary-300);color:var(--primary-800)}.form-button--primary.form-button--mode-ghost:hover:not(:disabled){background:rgba(44,98,255,.06);color:var(--primary-700)}.form-button--primary.form-button--mode-ghost:active:not(:disabled){background:rgba(44,98,255,.12);color:var(--primary-800)}.form-button--neutral.form-button--mode-filled{background:var(--neutral-12);border:none;color:var(--white)}.form-button--neutral.form-button--mode-filled:hover:not(:disabled){background:var(--neutral-11)}.form-button--neutral.form-button--mode-filled:active:not(:disabled){background:var(--neutral-10)}.form-button--neutral.form-button--mode-stroke{background:transparent;border:1px solid var(--neutral-4);color:var(--neutral-12)}.form-button--neutral.form-button--mode-stroke:hover:not(:disabled){background:var(--neutral-3);border-color:var(--neutral-4);color:var(--neutral-12)}.form-button--neutral.form-button--mode-stroke:active:not(:disabled){background:var(--neutral-4);border-color:var(--neutral-7);color:var(--neutral-12)}.form-button--neutral.form-button--mode-lighter{background:var(--neutral-3);border:none;color:var(--neutral-12)}.form-button--neutral.form-button--mode-lighter:hover:not(:disabled){background:var(--neutral-2);color:var(--neutral-12)}.form-button--neutral.form-button--mode-lighter:active:not(:disabled){background:var(--neutral-1);color:var(--neutral-12)}.form-button--neutral.form-button--mode-ghost{background:none;border:none;color:var(--neutral-12)}.form-button--neutral.form-button--mode-ghost:hover:not(:disabled){background:var(--neutral-2);color:var(--neutral-12)}.form-button--neutral.form-button--mode-ghost:active:not(:disabled){background:var(--neutral-3);color:var(--neutral-12)}.form-button--radius-none{border-radius:0}.form-button--radius-soft.form-button--md,.form-button--radius-soft.form-button--sm{border-radius:6px}.form-button--radius-medium.form-button--md,.form-button--radius-medium.form-button--sm,.form-button--radius-soft.form-button--lg,.form-button--radius-soft.form-button--xlg{border-radius:8px}.form-button--radius-medium.form-button--lg,.form-button--radius-medium.form-button--xlg{border-radius:10px}.form-button--radius-pill{border-radius:999px}
147
+ </style>
@@ -0,0 +1,87 @@
1
+ import type { RouteLocationRaw } from 'vue-router';
2
+ /**
3
+ * Button variant types
4
+ */
5
+ type ButtonVariant = 'primary' | 'error' | 'success' | 'neutral';
6
+ /**
7
+ * Button size types
8
+ */
9
+ type ButtonSize = 'sm' | 'md' | 'lg' | 'xlg';
10
+ /**
11
+ * Icon position types
12
+ */
13
+ type IconPosition = 'left' | 'right';
14
+ /**
15
+ * Icon collection types
16
+ */
17
+ type IconCollection = 'custom' | 'currencies' | 'icons';
18
+ /**
19
+ * Button mode types
20
+ */
21
+ type ButtonMode = 'filled' | 'stroke' | 'lighter' | 'ghost';
22
+ /**
23
+ * Button radius types
24
+ */
25
+ type ButtonRadiusType = 'none' | 'soft' | 'medium' | 'pill';
26
+ /**
27
+ * Button component props interface
28
+ */
29
+ interface ButtonProps {
30
+ /** Button style variant */
31
+ variant?: ButtonVariant;
32
+ /** Navigation target (for NuxtLink) */
33
+ to?: string | RouteLocationRaw;
34
+ /** Button size */
35
+ size?: ButtonSize;
36
+ /** Icon name */
37
+ icon?: string;
38
+ /** Icon position relative to label */
39
+ iconPosition?: IconPosition;
40
+ /** Icon collection namespace */
41
+ iconCollection?: IconCollection;
42
+ /** Button label text */
43
+ label?: string;
44
+ /** Loading state label */
45
+ loadingLabel?: string;
46
+ /** Whether button has rounded corners */
47
+ rounded?: boolean;
48
+ /** Whether button is in loading state */
49
+ loading?: boolean;
50
+ /** External link href (renders as anchor) */
51
+ href?: string | null;
52
+ /** Whether button is disabled */
53
+ disabled?: boolean;
54
+ /** Button type attribute */
55
+ type?: 'button' | 'submit' | 'reset';
56
+ /** Button mode */
57
+ mode?: ButtonMode;
58
+ /** Radius type with size-aware values */
59
+ radiusType?: ButtonRadiusType;
60
+ }
61
+ declare var __VLS_19: {};
62
+ type __VLS_Slots = {} & {
63
+ default?: (props: typeof __VLS_19) => any;
64
+ };
65
+ declare const __VLS_component: import("vue").DefineComponent<ButtonProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
66
+ click: (event: MouseEvent) => any;
67
+ }, string, import("vue").PublicProps, Readonly<ButtonProps> & Readonly<{
68
+ onClick?: ((event: MouseEvent) => any) | undefined;
69
+ }>, {
70
+ size: ButtonSize;
71
+ type: "button" | "submit" | "reset";
72
+ variant: ButtonVariant;
73
+ iconPosition: IconPosition;
74
+ iconCollection: IconCollection;
75
+ rounded: boolean;
76
+ loading: boolean;
77
+ disabled: boolean;
78
+ mode: ButtonMode;
79
+ radiusType: ButtonRadiusType;
80
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
81
+ declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
82
+ export default _default;
83
+ type __VLS_WithSlots<T, S> = T & {
84
+ new (): {
85
+ $slots: S;
86
+ };
87
+ };
@@ -0,0 +1,9 @@
1
+ interface Props {
2
+ name: string;
3
+ size?: string | number;
4
+ class?: string;
5
+ }
6
+ declare const _default: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{}>, {
7
+ size: string | number;
8
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
9
+ export default _default;
@@ -0,0 +1,71 @@
1
+ <template>
2
+ <ClientOnly>
3
+ <!-- SVG Mode: Renders the full SVG with size override -->
4
+ <div v-if="iconContent" :class="iconClass" v-html="processedSvgContent" />
5
+
6
+ <!-- Empty placeholder when no icon content -->
7
+ <span v-else :style="{ width: iconStyle.width, height: iconStyle.height, display: 'inline-block' }"></span>
8
+
9
+ <template #fallback>
10
+ <!-- SSR placeholder - matches client placeholder exactly -->
11
+ <span :style="{ width: iconStyle.width, height: iconStyle.height, display: 'inline-block' }"></span>
12
+ </template>
13
+ </ClientOnly>
14
+ </template>
15
+
16
+ <script setup>
17
+ import { computed, ref, onMounted, watch } from "vue";
18
+ import { useIcon } from "../composables/useIcon";
19
+ const props = defineProps({
20
+ name: { type: String, required: true },
21
+ size: { type: [String, Number], required: false, default: 24 },
22
+ class: { type: String, required: false }
23
+ });
24
+ const { loadIcon, getFallbackIcon, getViewBox } = useIcon();
25
+ const iconContent = ref("");
26
+ onMounted(async () => {
27
+ await loadIconContent();
28
+ });
29
+ watch(
30
+ () => props.name,
31
+ async () => {
32
+ await loadIconContent();
33
+ }
34
+ );
35
+ const loadIconContent = async () => {
36
+ try {
37
+ iconContent.value = await loadIcon(props.name);
38
+ } catch (error) {
39
+ console.warn("Failed to load icon:", error);
40
+ iconContent.value = getFallbackIcon();
41
+ }
42
+ };
43
+ const iconClass = computed(() => {
44
+ const classes = ["icon"];
45
+ if (props.class) {
46
+ classes.push(props.class);
47
+ }
48
+ return classes.join(" ");
49
+ });
50
+ const iconStyle = computed(() => {
51
+ const size = typeof props.size === "number" ? `${props.size}px` : typeof props.size === "string" && !props.size.includes("px") ? `${props.size}px` : props.size;
52
+ return {
53
+ width: size,
54
+ height: size,
55
+ display: "inline-flex",
56
+ alignItems: "center",
57
+ justifyContent: "center"
58
+ };
59
+ });
60
+ const processedSvgContent = computed(() => {
61
+ if (!iconContent.value) return "";
62
+ const size = typeof props.size === "number" ? `${props.size}px` : typeof props.size === "string" && !props.size.includes("px") ? `${props.size}px` : props.size;
63
+ const [namespace, iconName] = props.name.split(":");
64
+ const viewBox = getViewBox(namespace, iconName);
65
+ return `<svg width="${size}" height="${size}" viewBox="${viewBox}" fill="none" xmlns="http://www.w3.org/2000/svg">${iconContent.value}</svg>`;
66
+ });
67
+ </script>
68
+
69
+ <style scoped>
70
+ .icon{color:inherit;display:inline-block;line-height:0}.icon :deep(svg){display:block}
71
+ </style>
@@ -0,0 +1,9 @@
1
+ interface Props {
2
+ name: string;
3
+ size?: string | number;
4
+ class?: string;
5
+ }
6
+ declare const _default: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{}>, {
7
+ size: string | number;
8
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
9
+ export default _default;
@@ -0,0 +1,129 @@
1
+ /**
2
+ * Input size types
3
+ */
4
+ type InputSize = 'sm' | 'md' | 'lg';
5
+ /**
6
+ * Icon position types
7
+ */
8
+ type IconPosition = 'left' | 'right';
9
+ /**
10
+ * Affix position types
11
+ */
12
+ type AffixPosition = 'left' | 'right';
13
+ /**
14
+ * Button variant types
15
+ */
16
+ type ButtonVariant = 'primary' | 'error' | 'success' | 'neutral';
17
+ /**
18
+ * Button size types
19
+ */
20
+ type ButtonSize = 'sm' | 'md' | 'lg' | 'xlg';
21
+ /**
22
+ * Select option interface
23
+ */
24
+ interface SelectOption {
25
+ value: string | number;
26
+ label: string;
27
+ icon?: string;
28
+ flag?: string;
29
+ }
30
+ /**
31
+ * Input component props interface
32
+ */
33
+ interface InputProps {
34
+ /** Input value (v-model) */
35
+ modelValue?: string | number;
36
+ /** Input type */
37
+ type?: string;
38
+ /** Placeholder text */
39
+ placeholder?: string;
40
+ /** Input label */
41
+ label?: string;
42
+ /** Input size */
43
+ size?: InputSize;
44
+ /** Icon name */
45
+ icon?: string;
46
+ /** Icon position */
47
+ iconPosition?: IconPosition;
48
+ /** External affix text */
49
+ affix?: string;
50
+ /** Affix position */
51
+ affixPosition?: AffixPosition;
52
+ /** Inline affix text (inside input) */
53
+ inlineAffix?: string;
54
+ /** Inline affix position */
55
+ inlineAffixPosition?: AffixPosition;
56
+ /** Whether input is password type */
57
+ password?: boolean;
58
+ /** Whether input is disabled */
59
+ disabled?: boolean;
60
+ /** Whether input is readonly */
61
+ readonly?: boolean;
62
+ /** Whether input is required */
63
+ required?: boolean;
64
+ /** Error messages */
65
+ errors?: string | string[];
66
+ /** Hint text */
67
+ hint?: string;
68
+ /** Whether to show button */
69
+ withButton?: boolean;
70
+ /** Button label */
71
+ buttonLabel?: string;
72
+ /** Button variant */
73
+ buttonVariant?: ButtonVariant;
74
+ /** Button size */
75
+ buttonSize?: ButtonSize;
76
+ /** Button disabled state */
77
+ buttonDisabled?: boolean;
78
+ /** Button loading state */
79
+ buttonLoading?: boolean;
80
+ /** Show password requirements validation */
81
+ showPasswordRequirements?: boolean;
82
+ /** Whether to show select dropdown */
83
+ withSelect?: boolean;
84
+ /** Select options */
85
+ selectOptions?: SelectOption[];
86
+ /** Selected option value */
87
+ selectedOption?: string | number;
88
+ /** Select placeholder */
89
+ selectPlaceholder?: string;
90
+ /** Radius type with standard values */
91
+ radiusType?: 'none' | 'soft' | 'medium' | 'pill';
92
+ }
93
+ declare const _default: import("vue").DefineComponent<InputProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
94
+ "update:modelValue": (value: string | number) => any;
95
+ focus: (event: FocusEvent) => any;
96
+ blur: (event: FocusEvent) => any;
97
+ keydown: (event: KeyboardEvent) => any;
98
+ "button-click": (event: MouseEvent) => any;
99
+ "update:selectedOption": (value: string | number) => any;
100
+ }, string, import("vue").PublicProps, Readonly<InputProps> & Readonly<{
101
+ "onUpdate:modelValue"?: ((value: string | number) => any) | undefined;
102
+ onFocus?: ((event: FocusEvent) => any) | undefined;
103
+ onBlur?: ((event: FocusEvent) => any) | undefined;
104
+ onKeydown?: ((event: KeyboardEvent) => any) | undefined;
105
+ "onButton-click"?: ((event: MouseEvent) => any) | undefined;
106
+ "onUpdate:selectedOption"?: ((value: string | number) => any) | undefined;
107
+ }>, {
108
+ size: InputSize;
109
+ type: string;
110
+ required: boolean;
111
+ iconPosition: IconPosition;
112
+ disabled: boolean;
113
+ radiusType: "none" | "soft" | "medium" | "pill";
114
+ placeholder: string;
115
+ affixPosition: AffixPosition;
116
+ inlineAffixPosition: AffixPosition;
117
+ password: boolean;
118
+ readonly: boolean;
119
+ errors: string | string[];
120
+ buttonVariant: ButtonVariant;
121
+ buttonSize: ButtonSize;
122
+ buttonDisabled: boolean;
123
+ buttonLoading: boolean;
124
+ showPasswordRequirements: boolean;
125
+ withSelect: boolean;
126
+ selectOptions: SelectOption[];
127
+ selectPlaceholder: string;
128
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
129
+ export default _default;