├── .eslintrc
├── .gitignore
├── README.md
├── bun.lockb
├── cosmos.config.json
├── cosmos
├── components
│ ├── block-button.fixture.tsx
│ ├── cosmos.decorator.tsx
│ ├── dialog-content.fixture.tsx
│ └── search.fixture.tsx
├── main.tsx
├── mock
│ ├── index.tsx
│ └── static
│ │ ├── accordion.png
│ │ ├── contact-person-list.png
│ │ ├── dealer-list.png
│ │ ├── dealers.png
│ │ ├── door-type-list.png
│ │ ├── featured-quote.png
│ │ ├── people.png
│ │ ├── product.png
│ │ └── quote.png
└── sanity
│ ├── content-array-button.fixture.tsx
│ ├── cosmos.decorator.tsx
│ ├── dialog.fixture.tsx
│ └── portable-text-button.fixture.tsx
├── index.html
├── package.json
├── postcss.config.js
├── src
├── components
│ ├── block-button.tsx
│ ├── block-group.tsx
│ ├── block-list.tsx
│ ├── dialog-content.tsx
│ ├── group-button.tsx
│ ├── groups-list.tsx
│ ├── provider.tsx
│ └── search.tsx
├── index.css
├── index.tsx
├── sanity
│ ├── content-array-button.tsx
│ ├── dialog.tsx
│ ├── portable-text-button.tsx
│ └── replacer.tsx
├── types.d.tsx
└── utils.tsx
├── static
├── base.png
└── search.png
├── tailwind.config.js
├── tsconfig.json
└── vite.config.ts
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "browser": true,
4 | "es2021": true,
5 | "node": true
6 | },
7 | "extends": [
8 | "eslint:recommended",
9 | "plugin:@typescript-eslint/recommended",
10 | "plugin:react/recommended",
11 | "plugin:prettier/recommended",
12 | "plugin:tailwindcss/recommended",
13 | "plugin:react-hooks/recommended",
14 | "plugin:jsx-a11y/recommended"
15 | ],
16 | "parser": "@typescript-eslint/parser",
17 | "parserOptions": {
18 | "ecmaFeatures": {
19 | "jsx": true
20 | },
21 | "ecmaVersion": 12,
22 | "sourceType": "module"
23 | },
24 | "plugins": [
25 | "@typescript-eslint",
26 | "prettier",
27 | "react",
28 | "react-hooks",
29 | "tailwindcss",
30 | "simple-import-sort"
31 | ],
32 | "ignorePatterns": [
33 | "dev-dist/**/*.*",
34 | "dist/**/*.*",
35 | "node_modules/**/*.*",
36 | "**/theme-dark.js",
37 | "**/theme-light.js"
38 | ],
39 | "settings": {
40 | "react": {
41 | "version": "detect"
42 | }
43 | },
44 | "rules": {
45 | "prettier/prettier": [
46 | "error",
47 | {
48 | "tabs": true,
49 | "tabWidth": 4,
50 | "bracketSpacing": false,
51 | "endOfLine": "auto",
52 | "printWidth": 100,
53 | "semi": true,
54 | "singleQuote": true
55 | }
56 | ],
57 | "@typescript-eslint/consistent-type-imports": "error",
58 | // disabled tailwindcss/no-custom-classname because it isn't loading the tailwind.config.js file
59 | "tailwindcss/no-custom-classname": "off",
60 | "@typescript-eslint/no-unused-vars": [
61 | "warn",
62 | {
63 | "varsIgnorePattern": "^_.*$"
64 | }
65 | ],
66 | "simple-import-sort/imports": [
67 | "error",
68 | {
69 | "groups": [
70 | // Packages `react` related packages come first.
71 | ["^react", "^@?\\w"],
72 | // Internal packages.
73 | ["^(@|components)(/.*|$)"],
74 | // Side effect imports.
75 | ["^\\u0000"],
76 | // Parent imports. Put `..` last.
77 | ["^\\.\\.(?!/?$)", "^\\.\\./?$"],
78 | // Other relative imports. Put same-folder imports and `.` last.
79 | ["^\\./(?=.*/)(?!/?$)", "^\\.(?!/?$)", "^\\./?$"],
80 | // Style imports.
81 | ["^.+\\.?(css)$"]
82 | ]
83 | }
84 | ],
85 | "simple-import-sort/exports": "error",
86 | "react/react-in-jsx-scope": "off"
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore
2 |
3 | # Logs
4 |
5 | logs
6 | _.log
7 | npm-debug.log_
8 | yarn-debug.log*
9 | yarn-error.log*
10 | lerna-debug.log*
11 | .pnpm-debug.log*
12 |
13 | # Caches
14 |
15 | .cache
16 |
17 | # Diagnostic reports (https://nodejs.org/api/report.html)
18 |
19 | report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
20 |
21 | # Runtime data
22 |
23 | pids
24 | _.pid
25 | _.seed
26 | *.pid.lock
27 |
28 | # Directory for instrumented libs generated by jscoverage/JSCover
29 |
30 | lib-cov
31 |
32 | # Coverage directory used by tools like istanbul
33 |
34 | coverage
35 | *.lcov
36 |
37 | # nyc test coverage
38 |
39 | .nyc_output
40 |
41 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
42 |
43 | .grunt
44 |
45 | # Bower dependency directory (https://bower.io/)
46 |
47 | bower_components
48 |
49 | # node-waf configuration
50 |
51 | .lock-wscript
52 |
53 | # Compiled binary addons (https://nodejs.org/api/addons.html)
54 |
55 | build/Release
56 |
57 | # Dependency directories
58 |
59 | node_modules/
60 | jspm_packages/
61 |
62 | # Snowpack dependency directory (https://snowpack.dev/)
63 |
64 | web_modules/
65 |
66 | # TypeScript cache
67 |
68 | *.tsbuildinfo
69 |
70 | # Optional npm cache directory
71 |
72 | .npm
73 |
74 | # Optional eslint cache
75 |
76 | .eslintcache
77 |
78 | # Optional stylelint cache
79 |
80 | .stylelintcache
81 |
82 | # Microbundle cache
83 |
84 | .rpt2_cache/
85 | .rts2_cache_cjs/
86 | .rts2_cache_es/
87 | .rts2_cache_umd/
88 |
89 | # Optional REPL history
90 |
91 | .node_repl_history
92 |
93 | # Output of 'npm pack'
94 |
95 | *.tgz
96 |
97 | # Yarn Integrity file
98 |
99 | .yarn-integrity
100 |
101 | # dotenv environment variable files
102 |
103 | .env
104 | .env.development.local
105 | .env.test.local
106 | .env.production.local
107 | .env.local
108 |
109 | # parcel-bundler cache (https://parceljs.org/)
110 |
111 | .parcel-cache
112 |
113 | # Next.js build output
114 |
115 | .next
116 | out
117 |
118 | # Nuxt.js build / generate output
119 |
120 | .nuxt
121 | dist
122 |
123 | # Gatsby files
124 |
125 | # Comment in the public line in if your project uses Gatsby and not Next.js
126 |
127 | # https://nextjs.org/blog/next-9-1#public-directory-support
128 |
129 | # public
130 |
131 | # vuepress build output
132 |
133 | .vuepress/dist
134 |
135 | # vuepress v2.x temp and cache directory
136 |
137 | .temp
138 |
139 | # Docusaurus cache and generated files
140 |
141 | .docusaurus
142 |
143 | # Serverless directories
144 |
145 | .serverless/
146 |
147 | # FuseBox cache
148 |
149 | .fusebox/
150 |
151 | # DynamoDB Local files
152 |
153 | .dynamodb/
154 |
155 | # TernJS port file
156 |
157 | .tern-port
158 |
159 | # Stores VSCode versions used for testing VSCode extensions
160 |
161 | .vscode-test
162 |
163 | # yarn v2
164 |
165 | .yarn/cache
166 | .yarn/unplugged
167 | .yarn/build-state.yml
168 | .yarn/install-state.gz
169 | .pnp.*
170 |
171 | # IntelliJ based IDEs
172 | .idea
173 |
174 | # Finder (MacOS) folder config
175 | .DS_Store
176 |
177 | # Cosmos
178 | cosmos-export
179 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # @selvklart/sanity-block-selector
2 |
3 | 
4 |
5 |
6 | ## In action
7 |
8 | 
9 | 
10 |
11 |
12 | ## Description
13 |
14 | Provides a component for overriding the default Sanity block selector - `WithBlockSelector`.
15 | There are two variants, to account for different situations:
16 | `content-array` - for the "Add Item" button at the bottom of content arrays
17 | `portable-text` - for the "..." buttons inside portable text editors
18 |
19 |
20 | ## Use
21 |
22 | The components should be used as custom input components for the fields you want to have this block selector.
23 |
24 | The `blockPreviews` field controls how the block options are rendered.
25 | Each member of the array defines a group, which corresponds to an accordion tab.
26 | Each group has a `title` and `blocks` it contains, where the keys of the `blocks` field correspond to the names of blocks in the `of` array.
27 | Inside each of these, you can set a `description` and a `imageURL` to an image that represents that block (like an icon, or a preview).
28 | Both of these fields are optional, so only the title of the block (as defined in the schema will be shown).
29 |
30 | The `showOther` field can be set to true to create an additional group, which displays all of the blocks defined in the schema that haven't been added to `blockPreviews`.
31 |
32 | The `excludedBlocks` field is an array of the names of the blocks you want to have hidden from the selector.
33 |
34 | With the `text` field, you can override all of the hardcoded text values in the block selector:
35 | - `addItem`: the text in the "Add item" button
36 | - `dialogTitle`: the title of the dialog
37 | - `searchPlaceholder`: the placeholder of the search input in the dialog
38 | - `other`: the name of the `Other` tab
39 |
40 | With the `replaceQueries`field, you can replace the default queries for replacing the built-in block selector buttons in Sanity. By default, the default queries should work, so you shouldn't need to change this. But you have the flexibility to do so if you need to. (This is useful in case Sanity changes the layout of the Studio, and this package doesn't manage to stay up to date with it.).
41 |
42 | These queries depend on the `type` option.
43 |
44 |
45 | ```ts
46 | {
47 | name: 'richPortableText',
48 | title: 'Text',
49 | type: 'array',
50 | of: [...],
51 | components: {
52 | input: WithBlockSelector({
53 | type: 'portable-text',
54 | blockPreviews: [
55 | {
56 | title: 'Content',
57 | blocks: {
58 | accordion: {
59 | description: ''.
60 | imageURL: '',
61 | }
62 | }
63 | }
64 | ],
65 | showOther: true,
66 | excludedBlocks: ['extendedBlock'],
67 | text: {
68 | addItem: 'Legg til blokk',
69 | },
70 | replaceQueries: [
71 | {
72 | level: 'field',
73 | query: '[data-testid="insert-menu-auto-collapse-menu"] [data-testid="insert-menu-button"]',
74 | },
75 | {
76 | level: 'document',
77 | query: 'div[data-testid="document-panel-portal"] #menu-button[data-testid="insert-menu-button"]',
78 | },
79 | ]
80 | })
81 | }
82 | }
83 | ```
84 |
85 |
86 | ## Scripts and getting this thing running
87 |
88 | To install dependencies:
89 |
90 | ```bash
91 | bun install
92 | ```
93 |
94 | To start the react-cosmos documentation:
95 |
96 | ```bash
97 | bun start
98 | ```
99 |
100 | To build the package:
101 |
102 | ```bash
103 | bun run build
104 | ```
105 |
106 | To publish the package (this will also build the package automatically):
107 |
108 | ```bash
109 | npm publish --access public
110 | ```
--------------------------------------------------------------------------------
/bun.lockb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/selvklart/sanity-block-selector/07065887f52531475e7c49ff5fb7235bd4ebb18a/bun.lockb
--------------------------------------------------------------------------------
/cosmos.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": [
3 | "react-cosmos-plugin-vite",
4 | "react-cosmos-plugin-boolean-input"
5 | ],
6 | "vite": {
7 | "indexPath": "cosmos/main.tsx"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/cosmos/components/block-button.fixture.tsx:
--------------------------------------------------------------------------------
1 | import {BlockButton} from '../../src/components/block-button';
2 | import type {Block} from '../../src/types.d';
3 | import {mockGroups} from '../mock';
4 |
5 | const BlockButtonFixture = (block: Block) => {
6 | return ;
7 | };
8 |
9 | const block = mockGroups[0].blocks[0];
10 | export default {
11 | plain: BlockButtonFixture({...block, description: undefined, imageURL: undefined}),
12 | 'with description': BlockButtonFixture({...block, imageURL: undefined}),
13 | 'with image': BlockButtonFixture({...block, description: undefined}),
14 | 'with all': BlockButtonFixture(block),
15 | };
16 |
--------------------------------------------------------------------------------
/cosmos/components/cosmos.decorator.tsx:
--------------------------------------------------------------------------------
1 | import type {PropsWithChildren} from 'react';
2 |
3 | import {cn} from '../../src/utils';
4 |
5 | import '../../src/index.css';
6 |
7 | const ComponentsDecorator = ({children}: PropsWithChildren) => {
8 | return
{children}
;
9 | };
10 |
11 | export default ComponentsDecorator;
12 |
--------------------------------------------------------------------------------
/cosmos/components/dialog-content.fixture.tsx:
--------------------------------------------------------------------------------
1 | import {DialogContent} from '../../src/components/dialog-content';
2 | import type {Group} from '../../src/types.d';
3 | import {mockGroups} from '../mock';
4 |
5 | const DialogContentFixture = (title: string, groups: Group[], filter: string) => {
6 | return ;
7 | };
8 |
9 | export default {
10 | normal: DialogContentFixture('Select block', mockGroups, ''),
11 | filtered: DialogContentFixture('Select block', mockGroups, 'feature'),
12 | 'no results': DialogContentFixture('Select block', mockGroups, 'empty'),
13 | };
14 |
--------------------------------------------------------------------------------
/cosmos/components/search.fixture.tsx:
--------------------------------------------------------------------------------
1 | import {Search} from '../../src/components/search';
2 |
3 | const SearchFixture = (value: string, onChange: () => void) => {
4 | return ;
5 | };
6 |
7 | export default {
8 | empty: SearchFixture('', () => {}),
9 | filled: SearchFixture('featured', () => {}),
10 | };
11 |
--------------------------------------------------------------------------------
/cosmos/main.tsx:
--------------------------------------------------------------------------------
1 | import {createRoot} from 'react-dom/client';
2 |
3 | const root = createRoot(document.getElementById('root')!);
4 | root.render(Hello, world!
);
5 |
--------------------------------------------------------------------------------
/cosmos/mock/index.tsx:
--------------------------------------------------------------------------------
1 | import type {Group} from '../../src/types.d';
2 |
3 | export const mockGroups: Group[] = [
4 | {
5 | title: 'Content',
6 | blocks: [
7 | {
8 | _key: 'accordion',
9 | name: 'accordion',
10 | title: 'Accordion',
11 | description: 'A list of expandable items',
12 | imageURL: new URL('./static/accordion.png', import.meta.url),
13 | },
14 | {
15 | _key: 'featured content',
16 | name: 'featured content',
17 | title: 'Featured Content',
18 | description: 'A list of featured content',
19 | imageURL: new URL('./static/article-list.png', import.meta.url),
20 | },
21 | {
22 | _key: 'featured content grid',
23 | name: 'featured content grid',
24 | title: 'Featured Content Grid',
25 | description: 'A grid of featured content',
26 | imageURL: new URL('./static/article-list-from-feed.png', import.meta.url),
27 | },
28 | {
29 | _key: 'featured link list',
30 | name: 'featured link list',
31 | title: 'Featured Link List',
32 | description: 'A list of featured links',
33 | imageURL: new URL('./static/article-selection.png', import.meta.url),
34 | },
35 | {
36 | _key: 'featured quote',
37 | name: 'featured quote',
38 | title: 'Featured Quote',
39 | description: 'A featured quote',
40 | imageURL: new URL('./static/contact-person-list.png', import.meta.url),
41 | },
42 | {
43 | _key: 'featured quotes',
44 | name: 'featured quotes',
45 | title: 'Featured Quotes',
46 | description: 'A list of featured quotes',
47 | imageURL: new URL('./static/contact-person-selection.png', import.meta.url),
48 | },
49 | {
50 | _key: 'shared content reference',
51 | name: 'shared content reference',
52 | title: 'Shared Content Reference',
53 | description: 'A list of shared content references',
54 | imageURL: new URL('./static/dealer-list.png', import.meta.url),
55 | },
56 | {
57 | _key: 'search box',
58 | name: 'search box',
59 | title: 'Search Box',
60 | imageURL: new URL('./static/dealer-map.png', import.meta.url),
61 | },
62 | {
63 | _key: 'tabbed content',
64 | name: 'tabbed content',
65 | title: 'Tabbed Content',
66 | imageURL: new URL('./static/dealer-selection.png', import.meta.url),
67 | },
68 | {
69 | _key: 'table',
70 | name: 'table',
71 | title: 'Table',
72 | imageURL: new URL('./static/document-group-block.png', import.meta.url),
73 | },
74 | ],
75 | },
76 | {
77 | title: 'Media',
78 | blocks: [
79 | {
80 | _key: 'images',
81 | name: 'images',
82 | title: 'Images',
83 | description: 'A list of images',
84 | imageURL: new URL('./static/document-group-list.png', import.meta.url),
85 | },
86 | {
87 | _key: 'images with actions',
88 | name: 'images with actions',
89 | title: 'Images With Actions',
90 | description: 'A list of images with actions',
91 | imageURL: new URL('./static/document-list.png', import.meta.url),
92 | },
93 | {
94 | _key: 'you-tube video',
95 | name: 'you-tube video',
96 | title: 'YouTube Video',
97 | description: 'A YouTube video',
98 | imageURL: new URL('./static/door-type-list.png', import.meta.url),
99 | },
100 | {
101 | _key: 'you-tube video selection',
102 | name: 'you-tube video selection',
103 | title: 'YouTube Video Selection',
104 | description: 'A list of YouTube videos with a selection',
105 | imageURL: new URL('./static/featured-content.png', import.meta.url),
106 | },
107 | ],
108 | },
109 | {
110 | title: 'Articles',
111 | blocks: [
112 | {
113 | _key: 'article list',
114 | name: 'article list',
115 | title: 'Article List',
116 | description: 'A list of articles',
117 | imageURL: new URL('./static/featured-content-grid.png', import.meta.url),
118 | },
119 | {
120 | _key: 'article list from feed',
121 | name: 'article list from feed',
122 | title: 'Article List From Feed',
123 | description: 'A list of articles from a feed',
124 | imageURL: new URL('./static/featured-link-list.png', import.meta.url),
125 | },
126 | {
127 | _key: 'article selection',
128 | name: 'article selection',
129 | title: 'Article Selection',
130 | description: 'A list of articles with a selection',
131 | imageURL: new URL('./static/featured-quote.png', import.meta.url),
132 | },
133 | {
134 | _key: 'guide list',
135 | name: 'guide list',
136 | title: 'Guide List',
137 | description: 'A list of guides',
138 | imageURL: new URL('./static/featured-quotes.png', import.meta.url),
139 | },
140 | {
141 | _key: 'inspirational story list',
142 | name: 'inspirational story list',
143 | title: 'Inspirational Story List',
144 | description: 'A list of inspirational stories',
145 | imageURL: new URL('./static/guide-list.png', import.meta.url),
146 | },
147 | ],
148 | },
149 | {
150 | title: 'Products',
151 | blocks: [
152 | {
153 | _key: 'door type list',
154 | name: 'door type list',
155 | title: 'Door Type List',
156 | description: 'A list of door types',
157 | imageURL: new URL('./static/images.png', import.meta.url),
158 | },
159 | {
160 | _key: 'window type list',
161 | name: 'window type list',
162 | title: 'Window Type List',
163 | description: 'A list of window types',
164 | imageURL: new URL('./static/images-with-actions.png', import.meta.url),
165 | },
166 | {
167 | _key: 'product type selection',
168 | name: 'product type selection',
169 | title: 'Product Type Selection',
170 | description: 'A list of product types with a selection',
171 | imageURL: new URL('./static/inspirational-story-list.png', import.meta.url),
172 | },
173 | {
174 | _key: 'product feature grid',
175 | name: 'product feature grid',
176 | title: 'Product Feature Grid',
177 | description: 'A grid of product features',
178 | imageURL: new URL('./static/interactive-content.png', import.meta.url),
179 | },
180 | {
181 | _key: 'interactive content',
182 | name: 'interactive content',
183 | title: 'Interactive Content',
184 | description: 'A list of interactive content',
185 | imageURL: new URL(
186 | './static/interactive-content-glass-function.png',
187 | import.meta.url,
188 | ),
189 | },
190 | {
191 | _key: 'interactive content glass function',
192 | name: 'interactive content glass function',
193 | title: 'Interactive Content Glass Function',
194 | description: 'A list of interactive content glass functions',
195 | imageURL: new URL('./static/interactive-content-glass-option.png', import.meta.url),
196 | },
197 | {
198 | _key: 'interactive content glass option',
199 | name: 'interactive content glass option',
200 | title: 'Interactive Content Glass Option',
201 | description: 'A list of interactive content glass options',
202 | imageURL: new URL('./static/interactive-content-material.png', import.meta.url),
203 | },
204 | {
205 | _key: 'interactive content material',
206 | name: 'interactive content material',
207 | title: 'Interactive Content Material',
208 | description: 'A list of interactive content materials',
209 | imageURL: new URL(
210 | './static/interactive-content-muntin-bar-style.png',
211 | import.meta.url,
212 | ),
213 | },
214 | {
215 | _key: 'interactive content muntin bar style',
216 | name: 'interactive content muntin bar style',
217 | title: 'Interactive Content Muntin Bar Style',
218 | description: 'A list of interactive content muntin bar styles',
219 | imageURL: new URL('./static/interactive-content-profile.png', import.meta.url),
220 | },
221 | {
222 | _key: 'interactive content profile',
223 | name: 'interactive content profile',
224 | title: 'Interactive Content Profile',
225 | description: 'A list of interactive content profiles',
226 | imageURL: new URL('./static/product-feature-grid.png', import.meta.url),
227 | },
228 | ],
229 | },
230 | {
231 | title: 'Documents',
232 | blocks: [
233 | {
234 | _key: 'document group block',
235 | name: 'document group block',
236 | title: 'Document Group Block',
237 | description: 'A block of document groups',
238 | imageURL: new URL('./static/product-type-selection.png', import.meta.url),
239 | },
240 | {
241 | _key: 'document group list',
242 | name: 'document group list',
243 | title: 'Document Group List',
244 | description: 'A list of document groups',
245 | imageURL: new URL('./static/search-box.png', import.meta.url),
246 | },
247 | {
248 | _key: 'document list',
249 | name: 'document list',
250 | title: 'Document List',
251 | description: 'A list of documents',
252 | imageURL: new URL('./static/shared-content-reference.png', import.meta.url),
253 | },
254 | ],
255 | },
256 | {
257 | title: 'Dealers',
258 | blocks: [
259 | {
260 | _key: 'dealer list',
261 | name: 'dealer list',
262 | title: 'Dealer List',
263 | description: 'A list of dealers',
264 | imageURL: new URL('./static/tabbed-content.png', import.meta.url),
265 | },
266 | {
267 | _key: 'dealer map',
268 | name: 'dealer map',
269 | title: 'Dealer Map',
270 | description: 'A map of dealers',
271 | imageURL: new URL('./static/table.png', import.meta.url),
272 | },
273 | {
274 | _key: 'dealer selection',
275 | name: 'dealer selection',
276 | title: 'Dealer Selection',
277 | description: 'A list of dealers with a selection',
278 | imageURL: new URL('./static/vacancy-list.png', import.meta.url),
279 | },
280 | ],
281 | },
282 | {
283 | title: 'People and positions',
284 | blocks: [
285 | {
286 | _key: 'contact person list',
287 | name: 'contact person list',
288 | title: 'Contact Person List',
289 | description: 'A list of contact persons',
290 | imageURL: new URL('./static/window-type-list.png', import.meta.url),
291 | },
292 | {
293 | _key: 'contact person selection',
294 | name: 'contact person selection',
295 | title: 'Contact Person Selection',
296 | description: 'A list of contact persons with a selection',
297 | imageURL: new URL('./static/you-tube-video.png', import.meta.url),
298 | },
299 | {
300 | _key: 'vacancy list',
301 | name: 'vacancy list',
302 | title: 'Vacancy List',
303 | description: 'A list of vacancies',
304 | imageURL: new URL('./static/you-tube-video-selection.png', import.meta.url),
305 | },
306 | ],
307 | },
308 | ];
309 |
--------------------------------------------------------------------------------
/cosmos/mock/static/accordion.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/selvklart/sanity-block-selector/07065887f52531475e7c49ff5fb7235bd4ebb18a/cosmos/mock/static/accordion.png
--------------------------------------------------------------------------------
/cosmos/mock/static/contact-person-list.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/selvklart/sanity-block-selector/07065887f52531475e7c49ff5fb7235bd4ebb18a/cosmos/mock/static/contact-person-list.png
--------------------------------------------------------------------------------
/cosmos/mock/static/dealer-list.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/selvklart/sanity-block-selector/07065887f52531475e7c49ff5fb7235bd4ebb18a/cosmos/mock/static/dealer-list.png
--------------------------------------------------------------------------------
/cosmos/mock/static/dealers.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/selvklart/sanity-block-selector/07065887f52531475e7c49ff5fb7235bd4ebb18a/cosmos/mock/static/dealers.png
--------------------------------------------------------------------------------
/cosmos/mock/static/door-type-list.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/selvklart/sanity-block-selector/07065887f52531475e7c49ff5fb7235bd4ebb18a/cosmos/mock/static/door-type-list.png
--------------------------------------------------------------------------------
/cosmos/mock/static/featured-quote.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/selvklart/sanity-block-selector/07065887f52531475e7c49ff5fb7235bd4ebb18a/cosmos/mock/static/featured-quote.png
--------------------------------------------------------------------------------
/cosmos/mock/static/people.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/selvklart/sanity-block-selector/07065887f52531475e7c49ff5fb7235bd4ebb18a/cosmos/mock/static/people.png
--------------------------------------------------------------------------------
/cosmos/mock/static/product.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/selvklart/sanity-block-selector/07065887f52531475e7c49ff5fb7235bd4ebb18a/cosmos/mock/static/product.png
--------------------------------------------------------------------------------
/cosmos/mock/static/quote.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/selvklart/sanity-block-selector/07065887f52531475e7c49ff5fb7235bd4ebb18a/cosmos/mock/static/quote.png
--------------------------------------------------------------------------------
/cosmos/sanity/content-array-button.fixture.tsx:
--------------------------------------------------------------------------------
1 | import {useFixtureInput} from 'react-cosmos/client';
2 |
3 | import {ContentArrayButton} from '../../src/sanity/content-array-button';
4 | import {mockGroups} from '../mock';
5 |
6 | const ContentArrayButtonFixture = () => {
7 | const [groups] = useFixtureInput('groups', mockGroups);
8 | const [open, setOpen] = useFixtureInput('open', false);
9 | return ;
10 | };
11 |
12 | export default ContentArrayButtonFixture;
13 |
--------------------------------------------------------------------------------
/cosmos/sanity/cosmos.decorator.tsx:
--------------------------------------------------------------------------------
1 | import type {PropsWithChildren} from 'react';
2 | import {ThemeProvider} from '@sanity/ui';
3 | import {buildTheme} from '@sanity/ui/theme';
4 |
5 | import {cn} from '../../src/utils';
6 |
7 | import '../../src/index.css';
8 |
9 | const ComponentsDecorator = ({children}: PropsWithChildren) => {
10 | const theme = buildTheme();
11 | return (
12 |
13 | {children}
14 |
15 | );
16 | };
17 |
18 | export default ComponentsDecorator;
19 |
--------------------------------------------------------------------------------
/cosmos/sanity/dialog.fixture.tsx:
--------------------------------------------------------------------------------
1 | import {Dialog} from '../../src/sanity/dialog';
2 | import type {Group} from '../../src/types.d';
3 | import {mockGroups} from '../mock';
4 |
5 | const DialogFixture = (groups: Group[]) => {
6 | return