@300codes/design-system 1.0.0 → 1.1.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/package.json +3 -2
- package/src/components/FlatIconButton/FlatIconButton.stories.ts +81 -0
- package/src/components/FlatIconButton/FlatIconButton.vue +54 -0
- package/src/components/FlatIconButton/index.ts +2 -0
- package/src/components/SelectInput/SelectInput.vue +2 -2
- package/src/components/TextInput/TextInput.vue +3 -3
- package/src/components/index.ts +1 -0
- package/src/css/tokens.css +12 -9
- package/src/components/TextInput/components/InputIconButton.vue +0 -54
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@300codes/design-system",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"src/components",
|
|
@@ -21,7 +21,8 @@
|
|
|
21
21
|
"./radio-input": "./src/components/RadioInput/index.ts",
|
|
22
22
|
"./tabs-list": "./src/components/TabsList/index.ts",
|
|
23
23
|
"./search-input": "./src/components/SearchInput/index.ts",
|
|
24
|
-
"./base-tooltip": "./src/components/BaseTooltip/index.ts"
|
|
24
|
+
"./base-tooltip": "./src/components/BaseTooltip/index.ts",
|
|
25
|
+
"./flat-icon-button": "./src/components/FlatIconButton/index.ts"
|
|
25
26
|
},
|
|
26
27
|
"scripts": {
|
|
27
28
|
"build": "vue-tsc --noEmit",
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/vue3-vite';
|
|
2
|
+
import type { ConcreteComponent } from 'vue';
|
|
3
|
+
import type { FlatIconButtonProps } from './FlatIconButton.vue';
|
|
4
|
+
import FlatIconButton from './FlatIconButton.vue';
|
|
5
|
+
|
|
6
|
+
const meta: Meta<FlatIconButtonProps> = {
|
|
7
|
+
title: 'Components/FlatIconButton',
|
|
8
|
+
component: FlatIconButton as unknown as ConcreteComponent<FlatIconButtonProps>,
|
|
9
|
+
tags: ['autodocs'],
|
|
10
|
+
argTypes: {
|
|
11
|
+
iconName: { control: 'text' },
|
|
12
|
+
iconPath: { control: 'text' },
|
|
13
|
+
iconSize: {
|
|
14
|
+
control: 'select',
|
|
15
|
+
options: ['xs', 'sm', 'md', 'lg', 'xl'],
|
|
16
|
+
},
|
|
17
|
+
ariaLabel: { control: 'text' },
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export default meta;
|
|
22
|
+
type Story = StoryObj<FlatIconButtonProps>;
|
|
23
|
+
|
|
24
|
+
export const Default: Story = {
|
|
25
|
+
args: {
|
|
26
|
+
iconName: 'close',
|
|
27
|
+
iconSize: 'sm',
|
|
28
|
+
ariaLabel: 'Close',
|
|
29
|
+
},
|
|
30
|
+
render: (args: FlatIconButtonProps) => ({
|
|
31
|
+
components: { FlatIconButton },
|
|
32
|
+
setup() {
|
|
33
|
+
return { args };
|
|
34
|
+
},
|
|
35
|
+
template: '<FlatIconButton v-bind="args" />',
|
|
36
|
+
}),
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const Search: Story = {
|
|
40
|
+
args: {
|
|
41
|
+
iconName: 'search',
|
|
42
|
+
iconSize: 'sm',
|
|
43
|
+
ariaLabel: 'Search',
|
|
44
|
+
},
|
|
45
|
+
render: (args: FlatIconButtonProps) => ({
|
|
46
|
+
components: { FlatIconButton },
|
|
47
|
+
setup() {
|
|
48
|
+
return { args };
|
|
49
|
+
},
|
|
50
|
+
template: '<FlatIconButton v-bind="args" />',
|
|
51
|
+
}),
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export const MediumSize: Story = {
|
|
55
|
+
args: {
|
|
56
|
+
iconName: 'close',
|
|
57
|
+
iconSize: 'md',
|
|
58
|
+
ariaLabel: 'Close',
|
|
59
|
+
},
|
|
60
|
+
render: (args: FlatIconButtonProps) => ({
|
|
61
|
+
components: { FlatIconButton },
|
|
62
|
+
setup() {
|
|
63
|
+
return { args };
|
|
64
|
+
},
|
|
65
|
+
template: '<FlatIconButton v-bind="args" />',
|
|
66
|
+
}),
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export const Sizes: Story = {
|
|
70
|
+
render: () => ({
|
|
71
|
+
components: { FlatIconButton },
|
|
72
|
+
template: `
|
|
73
|
+
<div class="flex items-center gap-4">
|
|
74
|
+
<FlatIconButton icon-name="close" icon-size="xs" aria-label="Close xs" />
|
|
75
|
+
<FlatIconButton icon-name="close" icon-size="sm" aria-label="Close sm" />
|
|
76
|
+
<FlatIconButton icon-name="close" icon-size="md" aria-label="Close md" />
|
|
77
|
+
<FlatIconButton icon-name="close" icon-size="lg" aria-label="Close lg" />
|
|
78
|
+
</div>
|
|
79
|
+
`,
|
|
80
|
+
}),
|
|
81
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { IconSize } from '../../types/icon';
|
|
3
|
+
import BaseIcon from '../BaseIcon/BaseIcon.vue';
|
|
4
|
+
|
|
5
|
+
export interface FlatIconButtonProps {
|
|
6
|
+
iconName: string;
|
|
7
|
+
iconPath?: string;
|
|
8
|
+
iconSize?: IconSize;
|
|
9
|
+
ariaLabel?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
withDefaults(defineProps<FlatIconButtonProps>(), {
|
|
13
|
+
iconPath: '/icons',
|
|
14
|
+
iconSize: 'sm',
|
|
15
|
+
ariaLabel: undefined,
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
const emit = defineEmits<{
|
|
19
|
+
click: [];
|
|
20
|
+
}>();
|
|
21
|
+
</script>
|
|
22
|
+
|
|
23
|
+
<template>
|
|
24
|
+
<button
|
|
25
|
+
type="button"
|
|
26
|
+
class="flatIconButton inline-flex items-center justify-center cursor-pointer"
|
|
27
|
+
:aria-label="ariaLabel"
|
|
28
|
+
@click="emit('click')"
|
|
29
|
+
>
|
|
30
|
+
<BaseIcon
|
|
31
|
+
:name="iconName"
|
|
32
|
+
:icon-path="iconPath"
|
|
33
|
+
:size="iconSize"
|
|
34
|
+
/>
|
|
35
|
+
</button>
|
|
36
|
+
</template>
|
|
37
|
+
|
|
38
|
+
<style scoped>
|
|
39
|
+
.flatIconButton {
|
|
40
|
+
color: var(--flatIconButton-fg, #0e161b);
|
|
41
|
+
background: var(--flatIconButton-bg, transparent);
|
|
42
|
+
padding: var(--flatIconButton-p, 0.25rem);
|
|
43
|
+
border-radius: var(--flatIconButton-radius, 9999px);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.flatIconButton:hover {
|
|
47
|
+
background-color: var(--flatIconButton-bg-hover, #f3f4f6);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.flatIconButton:focus-visible {
|
|
51
|
+
outline: 2px solid var(--flatIconButton-outline, #0066cc);
|
|
52
|
+
outline-offset: 1px;
|
|
53
|
+
}
|
|
54
|
+
</style>
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { ref, computed, nextTick, watch } from 'vue';
|
|
3
3
|
import { useMediaQuery, onClickOutside } from '@vueuse/core';
|
|
4
4
|
import BaseIcon from '../BaseIcon/BaseIcon.vue';
|
|
5
|
-
import
|
|
5
|
+
import FlatIconButton from '../FlatIconButton/FlatIconButton.vue';
|
|
6
6
|
|
|
7
7
|
export type SelectOption = string | { value: string; label: string };
|
|
8
8
|
|
|
@@ -259,7 +259,7 @@ watch(isMobile, () => {
|
|
|
259
259
|
>
|
|
260
260
|
{{ mobileTitle || placeholder }}
|
|
261
261
|
|
|
262
|
-
<
|
|
262
|
+
<FlatIconButton
|
|
263
263
|
icon-name="close"
|
|
264
264
|
aria-label="Close"
|
|
265
265
|
class="ml-auto"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { computed, ref, type Ref } from 'vue';
|
|
3
3
|
import type { IconSize } from '../../types/icon';
|
|
4
|
-
import
|
|
4
|
+
import FlatIconButton from '../FlatIconButton/FlatIconButton.vue';
|
|
5
5
|
|
|
6
6
|
export type InputType = 'text' | 'password' | 'email' | 'tel' | 'search';
|
|
7
7
|
export type FilterType = 'number' | 'number-dash' | 'alpha' | 'alpha-space';
|
|
@@ -124,7 +124,7 @@ defineExpose<{ el: Ref<HTMLInputElement | undefined> }>({ el });
|
|
|
124
124
|
@keyup.enter="emit('enter')"
|
|
125
125
|
>
|
|
126
126
|
|
|
127
|
-
<
|
|
127
|
+
<FlatIconButton
|
|
128
128
|
v-if="iconLeft"
|
|
129
129
|
:icon-name="iconLeft.name"
|
|
130
130
|
:icon-path="iconLeft.iconPath"
|
|
@@ -134,7 +134,7 @@ defineExpose<{ el: Ref<HTMLInputElement | undefined> }>({ el });
|
|
|
134
134
|
@click="emit('clickIcon', 'left')"
|
|
135
135
|
/>
|
|
136
136
|
|
|
137
|
-
<
|
|
137
|
+
<FlatIconButton
|
|
138
138
|
v-if="iconRight"
|
|
139
139
|
:icon-name="iconRight.name"
|
|
140
140
|
:icon-path="iconRight.iconPath"
|
package/src/components/index.ts
CHANGED
package/src/css/tokens.css
CHANGED
|
@@ -182,15 +182,6 @@
|
|
|
182
182
|
--input-border-color-disabled: theme(--color-input-border-disabled);
|
|
183
183
|
--input-placeholder-fg-disabled: theme(--color-input-placeholder-disabled);
|
|
184
184
|
|
|
185
|
-
/* icon button */
|
|
186
|
-
--input-icon-bg: transparent;
|
|
187
|
-
--input-icon-fg: theme(--color-input-icon);
|
|
188
|
-
--input-icon-fg-hover: theme(--color-input-icon-hover);
|
|
189
|
-
--input-icon-bg-hover: theme(--color-input-icon-bg-hover);
|
|
190
|
-
--input-icon-outline: theme(--color-outline);
|
|
191
|
-
--input-icon-p: theme(--spacing-1);
|
|
192
|
-
--input-icon-radius: theme(--radius-full);
|
|
193
|
-
|
|
194
185
|
/* ────────────────────────────────────────────────
|
|
195
186
|
* TextInput — sizing
|
|
196
187
|
* ──────────────────────────────────────────────── */
|
|
@@ -382,6 +373,18 @@
|
|
|
382
373
|
--baseTooltip-lg-arrow-half-w: theme(--spacing-3); /* lg half-width 12px */
|
|
383
374
|
--baseTooltip-lg-arrow-h: theme(--spacing-4); /* lg arrow height 16px */
|
|
384
375
|
|
|
376
|
+
/* ────────────────────────────────────────────────
|
|
377
|
+
* FlatIconButton
|
|
378
|
+
* ──────────────────────────────────────────────── */
|
|
379
|
+
|
|
380
|
+
--flatIconButton-bg: transparent;
|
|
381
|
+
--flatIconButton-fg: theme(--color-input-icon);
|
|
382
|
+
--flatIconButton-fg-hover: theme(--color-input-icon-hover);
|
|
383
|
+
--flatIconButton-bg-hover: theme(--color-input-icon-bg-hover);
|
|
384
|
+
--flatIconButton-outline: theme(--color-outline);
|
|
385
|
+
--flatIconButton-p: theme(--spacing-1);
|
|
386
|
+
--flatIconButton-radius: theme(--radius-full);
|
|
387
|
+
|
|
385
388
|
/* ────────────────────────────────────────────────
|
|
386
389
|
* TabsList
|
|
387
390
|
* ──────────────────────────────────────────────── */
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
import type { IconSize } from '../../../types/icon';
|
|
3
|
-
import BaseIcon from '../../BaseIcon/BaseIcon.vue';
|
|
4
|
-
|
|
5
|
-
export interface InputIconButtonProps {
|
|
6
|
-
iconName: string;
|
|
7
|
-
iconPath?: string;
|
|
8
|
-
iconSize?: IconSize;
|
|
9
|
-
ariaLabel?: string;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
withDefaults(defineProps<InputIconButtonProps>(), {
|
|
13
|
-
iconPath: '/icons',
|
|
14
|
-
iconSize: 'sm',
|
|
15
|
-
ariaLabel: undefined,
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
const emit = defineEmits<{
|
|
19
|
-
click: [];
|
|
20
|
-
}>();
|
|
21
|
-
</script>
|
|
22
|
-
|
|
23
|
-
<template>
|
|
24
|
-
<button
|
|
25
|
-
type="button"
|
|
26
|
-
class="inputIconButton inline-flex items-center justify-center cursor-pointer"
|
|
27
|
-
:aria-label="ariaLabel"
|
|
28
|
-
@click="emit('click')"
|
|
29
|
-
>
|
|
30
|
-
<BaseIcon
|
|
31
|
-
:name="iconName"
|
|
32
|
-
:icon-path="iconPath"
|
|
33
|
-
:size="iconSize"
|
|
34
|
-
/>
|
|
35
|
-
</button>
|
|
36
|
-
</template>
|
|
37
|
-
|
|
38
|
-
<style scoped>
|
|
39
|
-
.inputIconButton {
|
|
40
|
-
color: var(--input-icon-fg, #0e161b);
|
|
41
|
-
background: var(--input-icon-bg, transparent);
|
|
42
|
-
padding: var(--input-icon-p, 0.25rem);
|
|
43
|
-
border-radius: var(--input-icon-radius, 9999px);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
.inputIconButton:hover {
|
|
47
|
-
background-color: var(--input-icon-bg-hover, #f3f4f6);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
.inputIconButton:focus-visible {
|
|
51
|
-
outline: 2px solid var(--input-icon-outline, #0066cc);
|
|
52
|
-
outline-offset: 1px;
|
|
53
|
-
}
|
|
54
|
-
</style>
|