From 81e462facb5b3787550253f4bb22fa0f72a700b2 Mon Sep 17 00:00:00 2001 From: Damilare Anjorin Date: Sat, 22 Jul 2023 11:55:56 +0100 Subject: [PATCH 1/4] feat(visually-hidden): add visually hidden component --- package.json | 3 +- packages/components/visually-hidden/README.md | 10 +++ .../visually-hidden/build.config.ts | 12 ++++ .../components/visually-hidden/package.json | 47 +++++++++++++ .../visually-hidden/src/VisuallyHidden.ts | 68 +++++++++++++++++++ .../components/visually-hidden/src/index.ts | 1 + .../src/stories/VisuallyHidden.stories.ts | 43 ++++++++++++ .../src/stories/VisuallyHiddenDemo.vue | 18 +++++ .../src/visually-hidden.test.ts | 49 +++++++++++++ .../components/visually-hidden/tsconfig.json | 10 +++ .../components/visually-hidden/tsup.config.ts | 22 ++++++ pnpm-lock.yaml | 27 ++++++-- 12 files changed, 305 insertions(+), 5 deletions(-) create mode 100644 packages/components/visually-hidden/README.md create mode 100644 packages/components/visually-hidden/build.config.ts create mode 100644 packages/components/visually-hidden/package.json create mode 100644 packages/components/visually-hidden/src/VisuallyHidden.ts create mode 100644 packages/components/visually-hidden/src/index.ts create mode 100644 packages/components/visually-hidden/src/stories/VisuallyHidden.stories.ts create mode 100644 packages/components/visually-hidden/src/stories/VisuallyHiddenDemo.vue create mode 100644 packages/components/visually-hidden/src/visually-hidden.test.ts create mode 100644 packages/components/visually-hidden/tsconfig.json create mode 100644 packages/components/visually-hidden/tsup.config.ts diff --git a/package.json b/package.json index cba0fe840..4cc5a4d19 100644 --- a/package.json +++ b/package.json @@ -48,6 +48,7 @@ "@oku-ui/provide": "workspace:^", "@oku-ui/separator": "workspace:^", "@oku-ui/switch": "workspace:^", + "@oku-ui/visually-hidden": "workspace:^", "@oku-ui/toggle": "workspace:^", "@oku-ui/use-composable": "workspace:^", "@oku-ui/utils": "workspace:^", @@ -102,7 +103,7 @@ }, "lint-staged": { "*.{[jt]s?(x),vue}": [ - "npx pnpm lint:fix" + "pnpm lint:fix" ] } } diff --git a/packages/components/visually-hidden/README.md b/packages/components/visually-hidden/README.md new file mode 100644 index 000000000..5ed5eadff --- /dev/null +++ b/packages/components/visually-hidden/README.md @@ -0,0 +1,10 @@ +# `@oku-ui/example` + +## Installation + +```sh +$ pnpm add @oku-ui/example +``` + +## Usage +... \ No newline at end of file diff --git a/packages/components/visually-hidden/build.config.ts b/packages/components/visually-hidden/build.config.ts new file mode 100644 index 000000000..b972b9a78 --- /dev/null +++ b/packages/components/visually-hidden/build.config.ts @@ -0,0 +1,12 @@ +import { defineBuildConfig } from 'unbuild' + +export default defineBuildConfig({ + entries: [ + { + builder: 'mkdist', + input: './src/', + pattern: ['**/!(*.test|*.stories).ts'], + }, + ], + declaration: true, +}) diff --git a/packages/components/visually-hidden/package.json b/packages/components/visually-hidden/package.json new file mode 100644 index 000000000..5d399e380 --- /dev/null +++ b/packages/components/visually-hidden/package.json @@ -0,0 +1,47 @@ +{ + "name": "@oku-ui/visually-hidden", + "type": "module", + "version": "0.0.0", + "license": "MIT", + "source": "src/index.ts", + "funding": "https://github.com/sponsors/productdevbook", + "homepage": "https://oku-ui.com/primitives", + "repository": { + "type": "git", + "url": "git+https://github.com/oku-ui/primitives.git" + }, + "bugs": { + "url": "https://github.com/oku-ui/primitives/issues" + }, + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.mjs" + } + }, + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "files": [ + "dist" + ], + "engines": { + "node": ">=18" + }, + "scripts": { + "build": "tsup", + "dev": "tsup --watch" + }, + "peerDependencies": { + "vue": "^3.3.0" + }, + "dependencies": { + "@oku-ui/primitive": "latest", + "@oku-ui/use-composable": "latest" + }, + "devDependencies": { + "tsconfig": "workspace:^" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/packages/components/visually-hidden/src/VisuallyHidden.ts b/packages/components/visually-hidden/src/VisuallyHidden.ts new file mode 100644 index 000000000..f6d3b3ac6 --- /dev/null +++ b/packages/components/visually-hidden/src/VisuallyHidden.ts @@ -0,0 +1,68 @@ +import { Primitive } from '@oku-ui/primitive' +import type { + ElementType, + MergeProps, + PrimitiveProps, +} from '@oku-ui/primitive' +import { useRef } from '@oku-ui/use-composable' +import type { CSSProperties } from 'vue' +import { defineComponent, h } from 'vue' + +const NAME = 'OkuVisuallyHidden' + +type VisuallyHiddenElement = ElementType<'button'> + +interface VisuallyHiddenProps extends PrimitiveProps {} + +const VisuallyHidden = defineComponent({ + name: NAME, + inheritAttrs: false, + props: { + asChild: { + type: Boolean, + default: undefined, + }, + }, + setup(props, { attrs, expose }) { + const { ...visuallyHiddenAttrs } = attrs as VisuallyHiddenElement + + const { $el, newRef } = useRef() + + expose({ + innerRef: $el, + }) + + const originalReturn = () => + h(Primitive.span, { + ref: newRef, + asChild: props.asChild, + ...visuallyHiddenAttrs, + style: { + position: 'absolute', + border: 0, + width: 1, + height: 1, + padding: 0, + margin: -1, + overflow: 'hidden', + clip: 'rect(0, 0, 0, 0)', + whiteSpace: 'nowrap', + wordWrap: 'normal', + ...(visuallyHiddenAttrs.style as CSSProperties), + }, + }) + + return originalReturn as unknown as { + innerRef: VisuallyHiddenElement + } + }, +}) + +type _VisuallyHidden = MergeProps + +const OkuVisuallyHidden = VisuallyHidden as typeof VisuallyHidden & +(new () => { $props: _VisuallyHidden }) + +export { OkuVisuallyHidden } + +export type { VisuallyHiddenProps } diff --git a/packages/components/visually-hidden/src/index.ts b/packages/components/visually-hidden/src/index.ts new file mode 100644 index 000000000..06f81174b --- /dev/null +++ b/packages/components/visually-hidden/src/index.ts @@ -0,0 +1 @@ +export * from './VisuallyHidden' diff --git a/packages/components/visually-hidden/src/stories/VisuallyHidden.stories.ts b/packages/components/visually-hidden/src/stories/VisuallyHidden.stories.ts new file mode 100644 index 000000000..d1e1b8cb1 --- /dev/null +++ b/packages/components/visually-hidden/src/stories/VisuallyHidden.stories.ts @@ -0,0 +1,43 @@ +import type { Meta, StoryObj } from '@storybook/vue3' +import type { IVisuallyHiddenProps } from './VisuallyHiddenDemo.vue' +import OkuVisuallyHiddenComponent from './VisuallyHiddenDemo.vue' + +interface StoryProps extends IVisuallyHiddenProps {} + +const meta = { + title: 'Utilities/VisuallyHidden', + component: OkuVisuallyHiddenComponent, + args: { + template: '#1', + }, + argTypes: { + template: { + control: 'text', + }, + }, + tags: ['autodocs'], +} satisfies Meta & { + args: StoryProps +} + +export default meta +type Story = StoryObj & { + args: StoryProps +} + +export const Styled: Story = { + args: { + template: '#1', + // allShow: true, + }, + + render: (args: any) => ({ + components: { OkuVisuallyHiddenComponent }, + setup() { + return { args } + }, + template: ` + + `, + }), +} diff --git a/packages/components/visually-hidden/src/stories/VisuallyHiddenDemo.vue b/packages/components/visually-hidden/src/stories/VisuallyHiddenDemo.vue new file mode 100644 index 000000000..292805b2f --- /dev/null +++ b/packages/components/visually-hidden/src/stories/VisuallyHiddenDemo.vue @@ -0,0 +1,18 @@ + + + diff --git a/packages/components/visually-hidden/src/visually-hidden.test.ts b/packages/components/visually-hidden/src/visually-hidden.test.ts new file mode 100644 index 000000000..63b6cc14a --- /dev/null +++ b/packages/components/visually-hidden/src/visually-hidden.test.ts @@ -0,0 +1,49 @@ +import { mount } from '@vue/test-utils' +import { describe, expect, it } from 'vitest' +import { OkuVisuallyHidden } from '.' + +describe('OkuVisuallyHidden', () => { + it('renders correctly with default props', () => { + const wrapper = mount(OkuVisuallyHidden) + expect(wrapper.exists()).toBe(true) + + expect(wrapper.element.tagName.toLowerCase()).toBe('span') + + const style = wrapper.element.getAttribute('style') + expect(style).toBe( + 'position: absolute; border: 0px; padding: 0px; overflow: hidden; clip: rect(0px, 0px, 0px, 0px); white-space: nowrap; word-wrap: normal;', + ) + + // The component should have a ref named 'innerRef' + expect(wrapper.vm.innerRef).toBeDefined() + expect(wrapper.vm.innerRef.tagName.toLowerCase()).toBe('span') + }) + + it('applies ref correctly', () => { + const wrapper = mount(OkuVisuallyHidden) + expect(wrapper.vm.innerRef).toBeDefined() + expect(wrapper.vm.innerRef.tagName.toLowerCase()).toBe('span') + }) + + it('renders correctly with custom style', () => { + const style = { + background: 'red', + color: 'white', + } + + const wrapper = mount(OkuVisuallyHidden, { + attrs: { + style, + }, + }) + + const inlineStyle = wrapper.element.getAttribute('style') + expect(inlineStyle).toContain('position: absolute;') + expect(inlineStyle).toContain('border: 0px;') + expect(inlineStyle).toContain('overflow: hidden;') + expect(inlineStyle).toContain('white-space: nowrap;') + expect(inlineStyle).toContain('word-wrap: normal;') + expect(inlineStyle).toContain('background: red;') + expect(inlineStyle).toContain('color: white;') + }) +}) diff --git a/packages/components/visually-hidden/tsconfig.json b/packages/components/visually-hidden/tsconfig.json new file mode 100644 index 000000000..b8dfa9041 --- /dev/null +++ b/packages/components/visually-hidden/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "tsconfig/node16.json", + "compilerOptions": { + "rootDir": "src", + "outDir": "dist" + }, + "include": [ + "src" + ] +} diff --git a/packages/components/visually-hidden/tsup.config.ts b/packages/components/visually-hidden/tsup.config.ts new file mode 100644 index 000000000..a2f7a0d8b --- /dev/null +++ b/packages/components/visually-hidden/tsup.config.ts @@ -0,0 +1,22 @@ +import { defineConfig } from 'tsup' +import pkg from './package.json' + +const external = [ + ...Object.keys(pkg.dependencies || {}), + ...Object.keys(pkg.peerDependencies || {}), +] + +export default defineConfig((options) => { + return [ + { + ...options, + entryPoints: ['src/index.ts'], + external, + dts: true, + clean: true, + target: 'node16', + format: ['esm'], + outExtension: () => ({ js: '.mjs' }), + }, + ] +}) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b126c98b4..25acb795c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -67,6 +67,9 @@ importers: '@oku-ui/utils': specifier: workspace:^ version: link:packages/core/utils + '@oku-ui/visually-hidden': + specifier: workspace:^ + version: link:packages/components/visually-hidden '@storybook/addon-essentials': specifier: ^7.0.27 version: 7.0.27(react-dom@18.2.0)(react@18.2.0) @@ -168,7 +171,7 @@ importers: version: 1.2.1 vite: specifier: 4.3.5 - version: 4.3.5 + version: 4.3.5(@types/node@18.16.19) vite-plugin-dts: specifier: ^3.3.0 version: 3.3.0(rollup@3.21.0)(typescript@5.1.6)(vite@4.3.5) @@ -428,6 +431,22 @@ importers: specifier: workspace:^ version: link:../../tsconfig + packages/components/visually-hidden: + dependencies: + '@oku-ui/primitive': + specifier: latest + version: link:../../core/primitive + '@oku-ui/use-composable': + specifier: latest + version: link:../../core/use-composable + vue: + specifier: ^3.3.0 + version: 3.3.4 + devDependencies: + tsconfig: + specifier: workspace:^ + version: link:../../tsconfig + packages/core/primitive: dependencies: vue: @@ -572,7 +591,7 @@ importers: version: 0.25.1(rollup@3.21.0)(vue@3.3.4) vite: specifier: 4.3.5 - version: 4.3.5 + version: 4.3.5(@types/node@18.16.19) vue-tsc: specifier: ^1.8.5 version: 1.8.5(typescript@5.1.6) @@ -13931,7 +13950,7 @@ packages: dependencies: '@types/node': 18.16.18 esbuild: 0.17.19 - postcss: 8.4.26 + postcss: 8.4.25 rollup: 3.22.0 optionalDependencies: fsevents: 2.3.2 @@ -13964,7 +13983,7 @@ packages: dependencies: '@types/node': 18.16.19 esbuild: 0.17.19 - postcss: 8.4.26 + postcss: 8.4.25 rollup: 3.22.0 optionalDependencies: fsevents: 2.3.2 From c311f083e589a8b1b04e78388049a4b250f9d93a Mon Sep 17 00:00:00 2001 From: Damilare Anjorin Date: Sat, 22 Jul 2023 12:00:27 +0100 Subject: [PATCH 2/4] chore: fix type --- packages/components/visually-hidden/src/visually-hidden.test.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/components/visually-hidden/src/visually-hidden.test.ts b/packages/components/visually-hidden/src/visually-hidden.test.ts index 63b6cc14a..8db27ed5c 100644 --- a/packages/components/visually-hidden/src/visually-hidden.test.ts +++ b/packages/components/visually-hidden/src/visually-hidden.test.ts @@ -16,12 +16,14 @@ describe('OkuVisuallyHidden', () => { // The component should have a ref named 'innerRef' expect(wrapper.vm.innerRef).toBeDefined() + // @ts-expect-error "working" expect(wrapper.vm.innerRef.tagName.toLowerCase()).toBe('span') }) it('applies ref correctly', () => { const wrapper = mount(OkuVisuallyHidden) expect(wrapper.vm.innerRef).toBeDefined() + // @ts-expect-error "working" expect(wrapper.vm.innerRef.tagName.toLowerCase()).toBe('span') }) From 45cc38c7ffbb2f69ab9425e1bfb7ee5568348231 Mon Sep 17 00:00:00 2001 From: Damilare Anjorin Date: Sat, 22 Jul 2023 12:07:45 +0100 Subject: [PATCH 3/4] chore: add to nuxt playground --- playground/nuxt3/package.json | 3 ++- playground/nuxt3/pages/visually-hidden.vue | 5 +++++ pnpm-lock.yaml | 3 +++ 3 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 playground/nuxt3/pages/visually-hidden.vue diff --git a/playground/nuxt3/package.json b/playground/nuxt3/package.json index a0000020c..8c545704b 100644 --- a/playground/nuxt3/package.json +++ b/playground/nuxt3/package.json @@ -18,7 +18,8 @@ "@oku-ui/label": "workspace:^", "@oku-ui/progress": "workspace:^", "@oku-ui/separator": "workspace:^", - "@oku-ui/switch": "workspace:^" + "@oku-ui/switch": "workspace:^", + "@oku-ui/visually-hidden": "workspace:^" }, "devDependencies": { "@nuxtjs/tailwindcss": "^6.8.0", diff --git a/playground/nuxt3/pages/visually-hidden.vue b/playground/nuxt3/pages/visually-hidden.vue new file mode 100644 index 000000000..4a1ed4497 --- /dev/null +++ b/playground/nuxt3/pages/visually-hidden.vue @@ -0,0 +1,5 @@ + + + diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 25acb795c..042bc8009 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -536,6 +536,9 @@ importers: '@oku-ui/switch': specifier: workspace:^ version: link:../../packages/components/switch + '@oku-ui/visually-hidden': + specifier: workspace:^ + version: link:../../packages/components/visually-hidden devDependencies: '@nuxtjs/tailwindcss': specifier: ^6.8.0 From 9cb2591aeb58590d2fe7b5b79becd20d3509fea7 Mon Sep 17 00:00:00 2001 From: productdevbook Date: Sat, 22 Jul 2023 22:21:49 +0300 Subject: [PATCH 4/4] fix: package and demo --- packages/components/visually-hidden/README.md | 4 ++-- packages/components/visually-hidden/package.json | 3 ++- .../visually-hidden/src/stories/VisuallyHiddenDemo.vue | 2 +- tailwind.config.js | 3 --- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/packages/components/visually-hidden/README.md b/packages/components/visually-hidden/README.md index 5ed5eadff..249571778 100644 --- a/packages/components/visually-hidden/README.md +++ b/packages/components/visually-hidden/README.md @@ -1,9 +1,9 @@ -# `@oku-ui/example` +# `@oku-ui/visually-hidden` ## Installation ```sh -$ pnpm add @oku-ui/example +$ pnpm add @oku-ui/visually-hidden ``` ## Usage diff --git a/packages/components/visually-hidden/package.json b/packages/components/visually-hidden/package.json index 5d399e380..7487e02b3 100644 --- a/packages/components/visually-hidden/package.json +++ b/packages/components/visually-hidden/package.json @@ -8,7 +8,8 @@ "homepage": "https://oku-ui.com/primitives", "repository": { "type": "git", - "url": "git+https://github.com/oku-ui/primitives.git" + "url": "git+https://github.com/oku-ui/primitives.git", + "directory": "packages/components/visually-hidden" }, "bugs": { "url": "https://github.com/oku-ui/primitives/issues" diff --git a/packages/components/visually-hidden/src/stories/VisuallyHiddenDemo.vue b/packages/components/visually-hidden/src/stories/VisuallyHiddenDemo.vue index 292805b2f..6c18e1aa2 100644 --- a/packages/components/visually-hidden/src/stories/VisuallyHiddenDemo.vue +++ b/packages/components/visually-hidden/src/stories/VisuallyHiddenDemo.vue @@ -11,7 +11,7 @@ defineProps()