diff --git a/package-lock.json b/package-lock.json index 89c56f571..3c9eec3ea 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,6 +25,7 @@ "skyway-js": "^4.4.5", "text-field-edit": "^3.2.0", "throttle-debounce": "^5.0.0", + "ts-pattern": "^5.0.5", "turndown": "^7.1.1", "turndown-plugin-gfm": "^1.0.2", "vue": "^3.3.4", @@ -10706,6 +10707,11 @@ "node": ">=14" } }, + "node_modules/ts-pattern": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/ts-pattern/-/ts-pattern-5.0.5.tgz", + "integrity": "sha512-tL0w8U/pgaacOmkb9fRlYzWEUDCfVjjv9dD4wHTgZ61MjhuMt46VNWTG747NqW6vRzoWIKABVhFSOJ82FvXrfA==" + }, "node_modules/tslib": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.0.tgz", diff --git a/package.json b/package.json index ac5d800a0..eb6f25ab8 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "skyway-js": "^4.4.5", "text-field-edit": "^3.2.0", "throttle-debounce": "^5.0.0", + "ts-pattern": "^5.0.5", "turndown": "^7.1.1", "turndown-plugin-gfm": "^1.0.2", "vue": "^3.3.4", diff --git a/src/components/GroupManager/GroupListGroupEdit.vue b/src/components/GroupManager/GroupListGroupEdit.vue index a4436b452..986477471 100644 --- a/src/components/GroupManager/GroupListGroupEdit.vue +++ b/src/components/GroupManager/GroupListGroupEdit.vue @@ -29,7 +29,12 @@ :members="group.members" />
- +
diff --git a/src/components/Main/MainView/ChannelView/ChannelHeader/ChannelHeaderRelationPanel.vue b/src/components/Main/MainView/ChannelView/ChannelHeader/ChannelHeaderRelationPanel.vue index 03194fd7d..4cf74f46f 100644 --- a/src/components/Main/MainView/ChannelView/ChannelHeader/ChannelHeaderRelationPanel.vue +++ b/src/components/Main/MainView/ChannelView/ChannelHeader/ChannelHeaderRelationPanel.vue @@ -16,7 +16,7 @@ diff --git a/src/components/Main/MainView/ClipsView/ClipsSidebar/ClipsSidebarContent.vue b/src/components/Main/MainView/ClipsView/ClipsSidebar/ClipsSidebarContent.vue index bdde60c74..000cb27bc 100644 --- a/src/components/Main/MainView/ClipsView/ClipsSidebar/ClipsSidebarContent.vue +++ b/src/components/Main/MainView/ClipsView/ClipsSidebar/ClipsSidebarContent.vue @@ -23,7 +23,12 @@
- +
diff --git a/src/components/Main/MainView/MessageElement/MessageEditor.vue b/src/components/Main/MainView/MessageElement/MessageEditor.vue index 84b2f4d7f..2fa82db69 100644 --- a/src/components/Main/MainView/MessageElement/MessageEditor.vue +++ b/src/components/Main/MainView/MessageElement/MessageEditor.vue @@ -32,7 +32,7 @@
- + - +
diff --git a/src/components/Settings/ThemeTab/EditTheme.vue b/src/components/Settings/ThemeTab/EditTheme.vue index 929e22177..72ddafd8c 100644 --- a/src/components/Settings/ThemeTab/EditTheme.vue +++ b/src/components/Settings/ThemeTab/EditTheme.vue @@ -5,14 +5,14 @@ label="エクスポート" @click="onImportClick" :disabled="isImporterOpen" - color="secondary" + type="tertiary" :class="$style.element" /> --> @@ -20,7 +20,8 @@ --> @@ -31,7 +32,7 @@ diff --git a/src/components/UI/FormButton.vue b/src/components/UI/FormButton.vue index e29a84838..d4fca9676 100644 --- a/src/components/UI/FormButton.vue +++ b/src/components/UI/FormButton.vue @@ -3,7 +3,8 @@ :class="$style.container" :disabled="loading || disabled" :data-is-loading="$boolAttr(loading)" - :data-color="color" + :data-type="type" + :data-is-danger="$boolAttr(isDanger)" >
{{ label }}
import { computed } from 'vue' import LoadingSpinner from '/@/components/UI/LoadingSpinner.vue' +import { match, P } from 'ts-pattern' -const props = withDefaults( - defineProps<{ - label?: string - loading?: boolean - disabled?: boolean - color?: 'primary' | 'secondary' | 'error' | 'tertiary' - }>(), - { - label: '', - loading: false, - disabled: false, - color: 'primary' as const - } -) +interface Type { + type?: 'primary' | 'secondary' | 'tertiary' + isDanger?: boolean +} + +interface NonDangerType extends Type { + type?: 'primary' | 'secondary' | 'tertiary' + isDanger?: false +} +interface DangerType extends Type { + type?: 'primary' | 'secondary' + isDanger: true +} + +type Props = { + label?: string + loading?: boolean + disabled?: boolean +} & (NonDangerType | DangerType) + +const props = withDefaults(defineProps(), { + label: '', + loading: false, + disabled: false, + type: 'primary', + isDanger: false +}) const spinnerColor = computed(() => { - switch (props.color) { - case 'tertiary': - return 'accent-primary' - default: - return 'white' - } + return match([props.type, props.isDanger] as const) + .with(['primary', P._], () => 'white' as const) + .with(['secondary', true], () => 'accent-error' as const) + .with(['secondary', false], () => 'accent-primary' as const) + .with(['tertiary', P._], () => 'ui-secondary' as const) + .exhaustive() }) @@ -57,20 +72,26 @@ const spinnerColor = computed(() => { &[data-is-loading] { cursor: wait; } - &[data-color='primary'] { + &[data-type='primary'] { @include color-common-text-white-primary; @include background-accent-primary; + border-color: $theme-ui-primary-default; + } + &[data-type='secondary'] { + @include color-accent-primary; border-color: $theme-accent-primary-default; } - &[data-color='secondary'] { + &[data-type='tertiary'] { @include color-ui-secondary; border-color: $theme-ui-secondary-default; } - &[data-color='tertiary'] { - @include color-accent-primary; - border-color: $theme-accent-primary-default; + + &[data-type='primary'][data-is-danger] { + @include color-common-text-white-primary; + @include background-accent-error; + border-color: $theme-accent-error-default; } - &[data-color='error'] { + &[data-type='secondary'][data-is-danger] { color: $theme-accent-error-default; border-color: $theme-accent-error-default; } diff --git a/src/components/UI/LoadingSpinner.vue b/src/components/UI/LoadingSpinner.vue index cde9dbf11..2bfef2f70 100644 --- a/src/components/UI/LoadingSpinner.vue +++ b/src/components/UI/LoadingSpinner.vue @@ -5,7 +5,7 @@