@1001-digital/components 0.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 (52) hide show
  1. package/package.json +45 -0
  2. package/src/base/components/Actions.vue +57 -0
  3. package/src/base/components/Alert.vue +90 -0
  4. package/src/base/components/Button.vue +260 -0
  5. package/src/base/components/Card.vue +78 -0
  6. package/src/base/components/CardLink.vue +56 -0
  7. package/src/base/components/Dialog.vue +274 -0
  8. package/src/base/components/Dropdown.vue +167 -0
  9. package/src/base/components/DropdownCheckboxItem.vue +30 -0
  10. package/src/base/components/DropdownGroup.vue +9 -0
  11. package/src/base/components/DropdownItem.vue +23 -0
  12. package/src/base/components/DropdownLabel.vue +9 -0
  13. package/src/base/components/DropdownRadioGroup.vue +15 -0
  14. package/src/base/components/DropdownRadioItem.vue +29 -0
  15. package/src/base/components/DropdownSeparator.vue +7 -0
  16. package/src/base/components/DropdownSub.vue +58 -0
  17. package/src/base/components/Form.vue +27 -0
  18. package/src/base/components/FormCheckbox.vue +92 -0
  19. package/src/base/components/FormGroup.vue +39 -0
  20. package/src/base/components/FormInputGroup.vue +55 -0
  21. package/src/base/components/FormItem.vue +89 -0
  22. package/src/base/components/FormLabel.vue +39 -0
  23. package/src/base/components/FormRadioGroup.vue +118 -0
  24. package/src/base/components/FormSelect.vue +160 -0
  25. package/src/base/components/FormTextarea.vue +38 -0
  26. package/src/base/components/Icon.vue +29 -0
  27. package/src/base/components/Loading.vue +81 -0
  28. package/src/base/components/Popover.vue +182 -0
  29. package/src/base/components/Tag.vue +56 -0
  30. package/src/base/components/Tags.vue +13 -0
  31. package/src/base/components/Toasts.vue +254 -0
  32. package/src/base/components/Tooltip.vue +100 -0
  33. package/src/base/composables/time.ts +82 -0
  34. package/src/base/composables/toast.ts +40 -0
  35. package/src/base/icons.ts +20 -0
  36. package/src/base/link.ts +4 -0
  37. package/src/base/utils/format-number.ts +29 -0
  38. package/src/base/utils/time.ts +20 -0
  39. package/src/evm/components/EvmAccount.vue +28 -0
  40. package/src/evm/components/EvmConnect.vue +254 -0
  41. package/src/evm/components/EvmConnectorQR.vue +116 -0
  42. package/src/evm/components/EvmMetaMaskQR.vue +15 -0
  43. package/src/evm/components/EvmTransactionFlow.vue +327 -0
  44. package/src/evm/components/EvmWalletConnectQR.vue +13 -0
  45. package/src/evm/composables/base.ts +7 -0
  46. package/src/evm/composables/chainId.ts +41 -0
  47. package/src/evm/config.ts +32 -0
  48. package/src/evm/index.ts +25 -0
  49. package/src/evm/utils/addresses.ts +6 -0
  50. package/src/evm/utils/chains.ts +32 -0
  51. package/src/evm/utils/format-eth.ts +15 -0
  52. package/src/index.ts +68 -0
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@1001-digital/components",
3
+ "version": "0.0.1",
4
+ "type": "module",
5
+ "sideEffects": [
6
+ "*.css"
7
+ ],
8
+ "exports": {
9
+ ".": "./src/index.ts",
10
+ "./*": "./src/*"
11
+ },
12
+ "files": [
13
+ "src"
14
+ ],
15
+ "peerDependencies": {
16
+ "@wagmi/core": ">=3.0.0",
17
+ "@wagmi/vue": ">=0.4.0",
18
+ "viem": ">=2.0.0",
19
+ "vue": "^3.5.0",
20
+ "@1001-digital/styles": "^0.0.1"
21
+ },
22
+ "peerDependenciesMeta": {
23
+ "@wagmi/core": {
24
+ "optional": true
25
+ },
26
+ "@wagmi/vue": {
27
+ "optional": true
28
+ },
29
+ "viem": {
30
+ "optional": true
31
+ }
32
+ },
33
+ "dependencies": {
34
+ "@iconify/vue": "^5.0.0",
35
+ "@vueuse/core": "^14.2.0",
36
+ "luxon": "^3.7.0",
37
+ "qrcode": "^1.5.4",
38
+ "reka-ui": "^2.8.0"
39
+ },
40
+ "devDependencies": {
41
+ "@types/luxon": "^3.7.0",
42
+ "@types/qrcode": "^1.5.6",
43
+ "vue": "^3.5.0"
44
+ }
45
+ }
@@ -0,0 +1,57 @@
1
+ <template>
2
+ <menu class="actions">
3
+ <slot />
4
+ </menu>
5
+ </template>
6
+
7
+ <style scoped>
8
+ .actions {
9
+ margin: 0;
10
+ padding: 0;
11
+ border: 0;
12
+ display: flex;
13
+ align-items: center;
14
+ flex-wrap: wrap;
15
+ gap: var(--spacer-sm);
16
+
17
+ &:not(.left) {
18
+ justify-content: flex-end;
19
+ }
20
+
21
+ &:empty {
22
+ display: none !important;
23
+ }
24
+
25
+ & :deep(> a),
26
+ & :deep(> button),
27
+ & :deep(> .input-group),
28
+ & :deep(> .input-group > *) {
29
+ block-size: var(--form-item-height);
30
+
31
+ &.small {
32
+ block-size: var(--form-item-height-sm);
33
+ }
34
+ }
35
+
36
+ & :deep(> label) {
37
+ font-family: var(--font-family);
38
+ font-size: var(--ui-font-size);
39
+ font-weight: var(--ui-font-weight);
40
+ text-transform: var(--ui-text-transform);
41
+ letter-spacing: var(--ui-letter-spacing);
42
+ line-height: var(--ui-line-height);
43
+ display: flex;
44
+ align-items: center;
45
+ gap: var(--spacer-sm);
46
+ white-space: nowrap;
47
+ }
48
+
49
+ & :deep(.button) {
50
+ inline-size: auto;
51
+ }
52
+
53
+ & :deep(select) {
54
+ inline-size: auto;
55
+ }
56
+ }
57
+ </style>
@@ -0,0 +1,90 @@
1
+ <template>
2
+ <Transition name="fade">
3
+ <aside
4
+ v-if="!dismissed"
5
+ class="alert"
6
+ :class="[type]"
7
+ >
8
+ <button
9
+ v-if="dismissable"
10
+ @click="dismiss"
11
+ class="close"
12
+ >
13
+ <Icon type="close" />
14
+ </button>
15
+ <slot />
16
+ </aside>
17
+ </Transition>
18
+ </template>
19
+
20
+ <script setup lang="ts">
21
+ import { computed } from 'vue'
22
+ import { useLocalStorage } from '@vueuse/core'
23
+ import Icon from './Icon.vue'
24
+
25
+ const props = defineProps<{
26
+ type?: 'info' | 'error'
27
+ dismiss?: string
28
+ }>()
29
+
30
+ const dismissKey = computed(() => `alert:${props.dismiss}`)
31
+
32
+ const dismissed = useLocalStorage(dismissKey.value, false)
33
+ const dismissable = computed(() => !!props.dismiss)
34
+
35
+ const dismiss = () => {
36
+ dismissed.value = true
37
+ }
38
+ </script>
39
+
40
+ <style scoped>
41
+ @layer components {
42
+ .alert {
43
+ position: relative;
44
+ display: grid;
45
+ padding: var(--spacer-sm);
46
+ gap: var(--spacer-sm);
47
+ border: var(--border);
48
+ border-color: var(--alert-border-color);
49
+ background-color: var(--alert-background-color);
50
+ color: var(--alert-color);
51
+ font-family: var(--font-family);
52
+ font-size: var(--ui-font-size);
53
+ text-transform: var(--ui-text-transform);
54
+
55
+ &.info {
56
+ border-color: var(--alert-info-border-color);
57
+ background-color: var(--alert-info-background-color);
58
+ color: var(--alert-info-color);
59
+ }
60
+
61
+ &.error {
62
+ border-color: var(--alert-error-border-color);
63
+ background-color: var(--alert-error-background-color);
64
+ color: var(--alert-error-color);
65
+ }
66
+
67
+ & :deep(> h1) {
68
+ text-transform: uppercase;
69
+ font-weight: bold;
70
+ }
71
+
72
+ .close {
73
+ display: flex;
74
+ align-items: center;
75
+ justify-content: center;
76
+ position: absolute;
77
+ inline-size: var(--size-4);
78
+ block-size: var(--size-4);
79
+ padding: 0;
80
+ inset-block-start: var(--spacer-sm);
81
+ inset-inline-end: var(--spacer-sm);
82
+ background: none;
83
+
84
+ &:is(:hover, :active, :focus, .active) {
85
+ background: none;
86
+ }
87
+ }
88
+ }
89
+ }
90
+ </style>
@@ -0,0 +1,260 @@
1
+ <template>
2
+ <component
3
+ v-if="to"
4
+ :is="linkComponent"
5
+ v-bind="linkProps"
6
+ :class="['button']"
7
+ >
8
+ <slot />
9
+ </component>
10
+ <button v-else>
11
+ <slot />
12
+ </button>
13
+ </template>
14
+
15
+ <script setup lang="ts">
16
+ import { computed, inject } from 'vue'
17
+ import { LinkComponentKey } from '../link'
18
+
19
+ const props = withDefaults(
20
+ defineProps<{
21
+ to?: string | Record<string, any>
22
+ target?: string
23
+ exact?: boolean
24
+ }>(),
25
+ {
26
+ target: '_self',
27
+ },
28
+ )
29
+
30
+ const linkComponent = inject(LinkComponentKey, 'a')
31
+
32
+ const linkProps = computed(() => {
33
+ if (typeof linkComponent === 'string') {
34
+ return { href: props.to, target: props.target }
35
+ }
36
+ return { to: props.to, target: props.target, exact: props.exact }
37
+ })
38
+ </script>
39
+
40
+ <style scoped>
41
+ @layer components {
42
+ button,
43
+ a.button {
44
+ position: relative;
45
+ min-inline-size: fit-content;
46
+ inline-size: fit-content;
47
+ display: inline-flex;
48
+ justify-content: center;
49
+ align-items: center;
50
+ gap: var(--spacer-sm);
51
+
52
+ &:not(.unstyled) {
53
+ background: var(--button-background);
54
+ color: var(--button-color);
55
+ padding: var(--ui-padding-block) var(--ui-padding-inline);
56
+ border: none;
57
+ border-radius: var(--button-border-radius);
58
+ box-shadow: var(--border-shadow);
59
+ transition:
60
+ background var(--speed),
61
+ box-shadow var(--speed),
62
+ color var(--speed);
63
+ }
64
+
65
+ > span {
66
+ display: flex;
67
+ gap: var(--ui-padding-inline);
68
+ line-height: var(--ui-line-height);
69
+ justify-content: center;
70
+ text-align: center;
71
+ align-items: center;
72
+ inline-size: 100%;
73
+ block-size: 100%;
74
+ }
75
+
76
+ > .icon {
77
+ color: var(--button-icon-color);
78
+ transition: color var(--speed);
79
+ }
80
+
81
+ &:has(> .icon:first-child) {
82
+ padding-inline-start: calc(var(--ui-padding-inline) - var(--size-1));
83
+
84
+ &.small {
85
+ padding-inline-start: calc(var(--ui-padding-inline) / 2);
86
+ }
87
+ }
88
+
89
+ &:has(> .icon:first-child:last-child) {
90
+ padding: var(--ui-padding-block);
91
+ aspect-ratio: 1;
92
+
93
+ &.small {
94
+ padding: calc(var(--ui-padding-block) / 2);
95
+ }
96
+ }
97
+
98
+ &.non-interactive,
99
+ &[disabled]:not([disabled='false']) {
100
+ pointer-events: none;
101
+ }
102
+
103
+ &[disabled]:not([disabled='false']) {
104
+ color: var(--muted);
105
+ opacity: 0.5;
106
+ }
107
+
108
+ &.small {
109
+ padding: calc(var(--ui-padding-block) / 2)
110
+ calc(var(--ui-padding-inline) / 2);
111
+ min-block-size: 0;
112
+
113
+ > .icon {
114
+ inline-size: var(--size-3);
115
+ block-size: var(--size-3);
116
+ }
117
+ }
118
+
119
+ &.muted {
120
+ color: var(--muted);
121
+
122
+ > .icon {
123
+ color: var(--muted);
124
+ }
125
+
126
+ &:is(:hover, :active, :focus, .active) {
127
+ color: var(--color);
128
+
129
+ > .icon {
130
+ color: var(--color);
131
+ }
132
+ }
133
+ }
134
+
135
+ &.link {
136
+ box-shadow: none;
137
+ background: transparent;
138
+ line-height: inherit;
139
+ color: var(--color);
140
+ padding: 0;
141
+
142
+ > .icon {
143
+ align-self: center;
144
+ block-size: 1em;
145
+ inline-size: 1em;
146
+ }
147
+
148
+ &.muted {
149
+ color: var(--muted);
150
+
151
+ > .icon {
152
+ color: var(--muted);
153
+ }
154
+ }
155
+ }
156
+
157
+ &.inline {
158
+ display: inline-flex;
159
+ align-self: baseline;
160
+ align-items: baseline;
161
+ block-size: inherit;
162
+ margin: 0 !important;
163
+ padding: 0 var(--size-1) !important;
164
+ gap: 0.2em;
165
+ inline-size: min-content;
166
+ }
167
+
168
+ &.invisible {
169
+ position: absolute;
170
+ inset-inline-start: -200vw;
171
+ opacity: 0;
172
+ }
173
+
174
+ &.danger {
175
+ box-shadow: 0 0 0 var(--border-width) var(--error);
176
+ color: var(--error) !important;
177
+
178
+ > .icon {
179
+ color: var(--error);
180
+ }
181
+ }
182
+
183
+ /* Primary variant */
184
+ &.primary {
185
+ background: var(--button-primary-background);
186
+ box-shadow: 0 0 0 var(--border-width) var(--button-primary-border-color);
187
+ color: var(--button-primary-color);
188
+
189
+ > .icon {
190
+ color: var(--button-primary-color);
191
+ }
192
+
193
+ &:is(:hover, :active, :focus, .active) {
194
+ background: var(--button-primary-background-highlight);
195
+ box-shadow: 0 0 0 var(--border-width)
196
+ var(--button-primary-border-color-highlight);
197
+ color: var(--button-primary-color-highlight);
198
+
199
+ > .icon {
200
+ color: var(--button-primary-color-highlight);
201
+ }
202
+ }
203
+ }
204
+
205
+ /* Tertiary variant */
206
+ &.tertiary {
207
+ background: var(--button-tertiary-background);
208
+ box-shadow: 0 0 0 var(--border-width) var(--button-tertiary-border-color);
209
+ color: var(--button-tertiary-color);
210
+
211
+ > .icon {
212
+ color: var(--button-tertiary-color);
213
+ }
214
+
215
+ &:is(:hover, :active, :focus, .active) {
216
+ background: var(--button-tertiary-background-highlight);
217
+ box-shadow: 0 0 0 var(--border-width)
218
+ var(--button-tertiary-border-color-highlight);
219
+ color: var(--button-tertiary-color-highlight);
220
+
221
+ > .icon {
222
+ color: var(--button-tertiary-color-highlight);
223
+ }
224
+ }
225
+ }
226
+
227
+ &:is(:hover, :active, :focus, .active) {
228
+ background: var(--button-background-highlight);
229
+ box-shadow: var(--border-shadow-highlight);
230
+ color: var(--button-color-highlight);
231
+
232
+ > .icon {
233
+ color: var(--button-icon-color-highlight);
234
+ }
235
+
236
+ &.link {
237
+ background: transparent !important;
238
+ box-shadow: none;
239
+ color: var(--color);
240
+
241
+ > .icon {
242
+ color: var(--gray-z-7);
243
+ }
244
+
245
+ &.muted {
246
+ color: var(--color);
247
+
248
+ > .icon {
249
+ color: var(--gray-z-7);
250
+ }
251
+ }
252
+ }
253
+ }
254
+
255
+ &.centered {
256
+ margin: auto;
257
+ }
258
+ }
259
+ }
260
+ </style>
@@ -0,0 +1,78 @@
1
+ <template>
2
+ <component
3
+ :is="as"
4
+ class="card"
5
+ >
6
+ <slot />
7
+ </component>
8
+ </template>
9
+
10
+ <script setup lang="ts">
11
+ withDefaults(
12
+ defineProps<{
13
+ as?: string
14
+ }>(),
15
+ {
16
+ as: 'article',
17
+ },
18
+ )
19
+ </script>
20
+
21
+ <style scoped>
22
+ @layer components {
23
+ .card {
24
+ display: grid;
25
+ gap: var(--spacer);
26
+ background-color: var(--card-background);
27
+ block-size: 100%;
28
+ padding: var(--spacer);
29
+ transition:
30
+ background var(--speed),
31
+ border-color var(--speed);
32
+
33
+ &:not(.borderless) {
34
+ border: var(--card-border);
35
+ border-radius: var(--card-border-radius);
36
+
37
+ &:has(> .card-link) {
38
+ &:has(> .card-link:hover),
39
+ &:has(> .card-link:focus) {
40
+ border-color: var(--card-border-color-highlight);
41
+ }
42
+ }
43
+ }
44
+
45
+ &.borderless {
46
+ padding: 0;
47
+ }
48
+
49
+ &:has(> .card-link) {
50
+ &:has(> .card-link:hover),
51
+ &:has(> .card-link:focus) {
52
+ background-color: var(--card-background-highlight);
53
+ }
54
+ }
55
+
56
+ &.static {
57
+ background-color: var(--card-background);
58
+ }
59
+
60
+ &.highlight {
61
+ background-color: var(--card-background-highlight);
62
+ }
63
+
64
+ > * {
65
+ inline-size: 100%;
66
+ place-self: center;
67
+
68
+ &:first-child {
69
+ place-self: flex-start;
70
+ }
71
+
72
+ &:last-child {
73
+ place-self: flex-end;
74
+ }
75
+ }
76
+ }
77
+ }
78
+ </style>
@@ -0,0 +1,56 @@
1
+ <template>
2
+ <component
3
+ :is="linkComponent"
4
+ v-bind="linkProps"
5
+ class="card-link"
6
+ >
7
+ <span>{{ title }}</span>
8
+ </component>
9
+ </template>
10
+
11
+ <script setup lang="ts">
12
+ import { computed, inject } from 'vue'
13
+ import { LinkComponentKey } from '../link'
14
+
15
+ const props = withDefaults(
16
+ defineProps<{
17
+ to: string | Record<string, any>
18
+ title?: string
19
+ }>(),
20
+ {
21
+ title: 'View',
22
+ },
23
+ )
24
+
25
+ const linkComponent = inject(LinkComponentKey, 'a')
26
+
27
+ const linkProps = computed(() => {
28
+ if (typeof linkComponent === 'string') {
29
+ return { href: props.to }
30
+ }
31
+ return { to: props.to }
32
+ })
33
+ </script>
34
+
35
+ <style scoped>
36
+ a {
37
+ position: absolute;
38
+ z-index: 1;
39
+ left: 0;
40
+ right: 0;
41
+ bottom: 0;
42
+ top: 0;
43
+ border: 0;
44
+
45
+ span {
46
+ opacity: 0;
47
+ pointer-events: none;
48
+ }
49
+ }
50
+ </style>
51
+
52
+ <style>
53
+ *:has(> .card-link) {
54
+ position: relative;
55
+ }
56
+ </style>