Elevate visibility of form buttons

This commit is contained in:
Sam Becker 2024-04-06 17:25:27 -05:00
parent ad21d28f70
commit 8888674370
5 changed files with 205 additions and 167 deletions

View File

@ -35,7 +35,7 @@
"clsx": "^2.1.0",
"cmdk": "^1.0.0",
"date-fns": "^3.6.0",
"eslint": "9.0.0",
"eslint": "8.57.0",
"eslint-config-next": "14.1.4",
"exifr": "^7.1.3",
"framer-motion": "^11.0.25",

213
pnpm-lock.yaml generated
View File

@ -43,10 +43,10 @@ dependencies:
version: 18.2.24
'@typescript-eslint/eslint-plugin':
specifier: ^7.5.0
version: 7.5.0(@typescript-eslint/parser@7.5.0)(eslint@9.0.0)(typescript@5.4.4)
version: 7.5.0(@typescript-eslint/parser@7.5.0)(eslint@8.57.0)(typescript@5.4.4)
'@typescript-eslint/parser':
specifier: ^7.5.0
version: 7.5.0(eslint@9.0.0)(typescript@5.4.4)
version: 7.5.0(eslint@8.57.0)(typescript@5.4.4)
'@upstash/ratelimit':
specifier: ^1.0.3
version: 1.0.3
@ -84,11 +84,11 @@ dependencies:
specifier: ^3.6.0
version: 3.6.0
eslint:
specifier: 9.0.0
version: 9.0.0
specifier: 8.57.0
version: 8.57.0
eslint-config-next:
specifier: 14.1.4
version: 14.1.4(eslint@9.0.0)(typescript@5.4.4)
version: 14.1.4(eslint@8.57.0)(typescript@5.4.4)
exifr:
specifier: ^7.1.3
version: 7.1.3
@ -1186,13 +1186,13 @@ packages:
engines: {node: '>=10.0.0'}
dev: false
/@eslint-community/eslint-utils@4.4.0(eslint@9.0.0):
/@eslint-community/eslint-utils@4.4.0(eslint@8.57.0):
resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
dependencies:
eslint: 9.0.0
eslint: 8.57.0
eslint-visitor-keys: 3.4.3
dev: false
@ -1201,14 +1201,14 @@ packages:
engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
dev: false
/@eslint/eslintrc@3.0.2:
resolution: {integrity: sha512-wV19ZEGEMAC1eHgrS7UQPqsdEiCIbTKTasEfcXAigzoXICcqZSjBZEHlZwNVvKg6UBCjSlos84XiLqsRJnIcIg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
/@eslint/eslintrc@2.1.4:
resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dependencies:
ajv: 6.12.6
debug: 4.3.4
espree: 10.0.1
globals: 14.0.0
espree: 9.6.1
globals: 13.24.0
ignore: 5.3.1
import-fresh: 3.3.0
js-yaml: 4.1.0
@ -1218,9 +1218,9 @@ packages:
- supports-color
dev: false
/@eslint/js@9.0.0:
resolution: {integrity: sha512-RThY/MnKrhubF6+s1JflwUjPEsnCEmYCWwqa/aRISKWNXGZ9epUwft4bUMM35SdKF9xvBrLydAM1RDHd1Z//ZQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
/@eslint/js@8.57.0:
resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dev: false
/@fastify/busboy@2.1.0:
@ -1256,8 +1256,8 @@ packages:
resolution: {integrity: sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==}
dev: false
/@humanwhocodes/config-array@0.12.3:
resolution: {integrity: sha512-jsNnTBlMWuTpDkeE3on7+dWJi0D6fdDfeANj/w7MpS8ztROCoLvIO2nG0CcFj+E4k8j4QrSTh4Oryi3i2G669g==}
/@humanwhocodes/config-array@0.11.14:
resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==}
engines: {node: '>=10.10.0'}
dependencies:
'@humanwhocodes/object-schema': 2.0.3
@ -2937,7 +2937,7 @@ packages:
'@types/yargs-parser': 21.0.3
dev: false
/@typescript-eslint/eslint-plugin@7.5.0(@typescript-eslint/parser@7.5.0)(eslint@9.0.0)(typescript@5.4.4):
/@typescript-eslint/eslint-plugin@7.5.0(@typescript-eslint/parser@7.5.0)(eslint@8.57.0)(typescript@5.4.4):
resolution: {integrity: sha512-HpqNTH8Du34nLxbKgVMGljZMG0rJd2O9ecvr2QLYp+7512ty1j42KnsFwspPXg1Vh8an9YImf6CokUBltisZFQ==}
engines: {node: ^18.18.0 || >=20.0.0}
peerDependencies:
@ -2949,13 +2949,13 @@ packages:
optional: true
dependencies:
'@eslint-community/regexpp': 4.10.0
'@typescript-eslint/parser': 7.5.0(eslint@9.0.0)(typescript@5.4.4)
'@typescript-eslint/parser': 7.5.0(eslint@8.57.0)(typescript@5.4.4)
'@typescript-eslint/scope-manager': 7.5.0
'@typescript-eslint/type-utils': 7.5.0(eslint@9.0.0)(typescript@5.4.4)
'@typescript-eslint/utils': 7.5.0(eslint@9.0.0)(typescript@5.4.4)
'@typescript-eslint/type-utils': 7.5.0(eslint@8.57.0)(typescript@5.4.4)
'@typescript-eslint/utils': 7.5.0(eslint@8.57.0)(typescript@5.4.4)
'@typescript-eslint/visitor-keys': 7.5.0
debug: 4.3.4
eslint: 9.0.0
eslint: 8.57.0
graphemer: 1.4.0
ignore: 5.3.1
natural-compare: 1.4.0
@ -2966,7 +2966,7 @@ packages:
- supports-color
dev: false
/@typescript-eslint/parser@6.21.0(eslint@9.0.0)(typescript@5.4.4):
/@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.4):
resolution: {integrity: sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==}
engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies:
@ -2981,13 +2981,13 @@ packages:
'@typescript-eslint/typescript-estree': 6.21.0(typescript@5.4.4)
'@typescript-eslint/visitor-keys': 6.21.0
debug: 4.3.4
eslint: 9.0.0
eslint: 8.57.0
typescript: 5.4.4
transitivePeerDependencies:
- supports-color
dev: false
/@typescript-eslint/parser@7.5.0(eslint@9.0.0)(typescript@5.4.4):
/@typescript-eslint/parser@7.5.0(eslint@8.57.0)(typescript@5.4.4):
resolution: {integrity: sha512-cj+XGhNujfD2/wzR1tabNsidnYRaFfEkcULdcIyVBYcXjBvBKOes+mpMBP7hMpOyk+gBcfXsrg4NBGAStQyxjQ==}
engines: {node: ^18.18.0 || >=20.0.0}
peerDependencies:
@ -3002,7 +3002,7 @@ packages:
'@typescript-eslint/typescript-estree': 7.5.0(typescript@5.4.4)
'@typescript-eslint/visitor-keys': 7.5.0
debug: 4.3.4
eslint: 9.0.0
eslint: 8.57.0
typescript: 5.4.4
transitivePeerDependencies:
- supports-color
@ -3024,7 +3024,7 @@ packages:
'@typescript-eslint/visitor-keys': 7.5.0
dev: false
/@typescript-eslint/type-utils@7.5.0(eslint@9.0.0)(typescript@5.4.4):
/@typescript-eslint/type-utils@7.5.0(eslint@8.57.0)(typescript@5.4.4):
resolution: {integrity: sha512-A021Rj33+G8mx2Dqh0nMO9GyjjIBK3MqgVgZ2qlKf6CJy51wY/lkkFqq3TqqnH34XyAHUkq27IjlUkWlQRpLHw==}
engines: {node: ^18.18.0 || >=20.0.0}
peerDependencies:
@ -3035,9 +3035,9 @@ packages:
optional: true
dependencies:
'@typescript-eslint/typescript-estree': 7.5.0(typescript@5.4.4)
'@typescript-eslint/utils': 7.5.0(eslint@9.0.0)(typescript@5.4.4)
'@typescript-eslint/utils': 7.5.0(eslint@8.57.0)(typescript@5.4.4)
debug: 4.3.4
eslint: 9.0.0
eslint: 8.57.0
ts-api-utils: 1.2.1(typescript@5.4.4)
typescript: 5.4.4
transitivePeerDependencies:
@ -3098,19 +3098,19 @@ packages:
- supports-color
dev: false
/@typescript-eslint/utils@7.5.0(eslint@9.0.0)(typescript@5.4.4):
/@typescript-eslint/utils@7.5.0(eslint@8.57.0)(typescript@5.4.4):
resolution: {integrity: sha512-3vZl9u0R+/FLQcpy2EHyRGNqAS/ofJ3Ji8aebilfJe+fobK8+LbIFmrHciLVDxjDoONmufDcnVSF38KwMEOjzw==}
engines: {node: ^18.18.0 || >=20.0.0}
peerDependencies:
eslint: ^8.56.0
dependencies:
'@eslint-community/eslint-utils': 4.4.0(eslint@9.0.0)
'@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0)
'@types/json-schema': 7.0.15
'@types/semver': 7.5.6
'@typescript-eslint/scope-manager': 7.5.0
'@typescript-eslint/types': 7.5.0
'@typescript-eslint/typescript-estree': 7.5.0(typescript@5.4.4)
eslint: 9.0.0
eslint: 8.57.0
semver: 7.6.0
transitivePeerDependencies:
- supports-color
@ -3133,6 +3133,10 @@ packages:
eslint-visitor-keys: 3.4.3
dev: false
/@ungap/structured-clone@1.2.0:
resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==}
dev: false
/@upstash/core-analytics@0.0.7:
resolution: {integrity: sha512-lC2j5efqb1haX/fpTGaPUx1rue1WUkOZBVHDzCB7eMIVsRdFFp4xiHtyH/G9omiR1zj39fU5SCTWFiKJH3KOpw==}
engines: {node: '>=16.0.0'}
@ -4230,6 +4234,13 @@ packages:
esutils: 2.0.3
dev: false
/doctrine@3.0.0:
resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==}
engines: {node: '>=6.0.0'}
dependencies:
esutils: 2.0.3
dev: false
/dom-accessibility-api@0.5.16:
resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==}
dev: false
@ -4433,7 +4444,7 @@ packages:
source-map: 0.6.1
dev: false
/eslint-config-next@14.1.4(eslint@9.0.0)(typescript@5.4.4):
/eslint-config-next@14.1.4(eslint@8.57.0)(typescript@5.4.4):
resolution: {integrity: sha512-cihIahbhYAWwXJwZkAaRPpUi5t9aOi/HdfWXOjZeUOqNWXHD8X22kd1KG58Dc3MVaRx3HoR/oMGk2ltcrqDn8g==}
peerDependencies:
eslint: ^7.23.0 || ^8.0.0
@ -4444,14 +4455,14 @@ packages:
dependencies:
'@next/eslint-plugin-next': 14.1.4
'@rushstack/eslint-patch': 1.7.2
'@typescript-eslint/parser': 6.21.0(eslint@9.0.0)(typescript@5.4.4)
eslint: 9.0.0
'@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@5.4.4)
eslint: 8.57.0
eslint-import-resolver-node: 0.3.9
eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@9.0.0)
eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.5.0)(eslint@9.0.0)
eslint-plugin-jsx-a11y: 6.8.0(eslint@9.0.0)
eslint-plugin-react: 7.33.2(eslint@9.0.0)
eslint-plugin-react-hooks: 4.6.0(eslint@9.0.0)
eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0)
eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.5.0)(eslint@8.57.0)
eslint-plugin-jsx-a11y: 6.8.0(eslint@8.57.0)
eslint-plugin-react: 7.33.2(eslint@8.57.0)
eslint-plugin-react-hooks: 4.6.0(eslint@8.57.0)
typescript: 5.4.4
transitivePeerDependencies:
- eslint-import-resolver-webpack
@ -4468,7 +4479,7 @@ packages:
- supports-color
dev: false
/eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@9.0.0):
/eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0):
resolution: {integrity: sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==}
engines: {node: ^14.18.0 || >=16.0.0}
peerDependencies:
@ -4477,9 +4488,9 @@ packages:
dependencies:
debug: 4.3.4
enhanced-resolve: 5.15.0
eslint: 9.0.0
eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@9.0.0)
eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.5.0)(eslint@9.0.0)
eslint: 8.57.0
eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.5.0)(eslint@8.57.0)
fast-glob: 3.3.2
get-tsconfig: 4.7.2
is-core-module: 2.13.1
@ -4491,7 +4502,7 @@ packages:
- supports-color
dev: false
/eslint-module-utils@2.8.0(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@9.0.0):
/eslint-module-utils@2.8.0(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0):
resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==}
engines: {node: '>=4'}
peerDependencies:
@ -4512,16 +4523,16 @@ packages:
eslint-import-resolver-webpack:
optional: true
dependencies:
'@typescript-eslint/parser': 6.21.0(eslint@9.0.0)(typescript@5.4.4)
'@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@5.4.4)
debug: 3.2.7
eslint: 9.0.0
eslint: 8.57.0
eslint-import-resolver-node: 0.3.9
eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@9.0.0)
eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0)
transitivePeerDependencies:
- supports-color
dev: false
/eslint-module-utils@2.8.0(@typescript-eslint/parser@7.5.0)(eslint-import-resolver-node@0.3.9)(eslint@9.0.0):
/eslint-module-utils@2.8.0(@typescript-eslint/parser@7.5.0)(eslint-import-resolver-node@0.3.9)(eslint@8.57.0):
resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==}
engines: {node: '>=4'}
peerDependencies:
@ -4542,15 +4553,15 @@ packages:
eslint-import-resolver-webpack:
optional: true
dependencies:
'@typescript-eslint/parser': 7.5.0(eslint@9.0.0)(typescript@5.4.4)
'@typescript-eslint/parser': 7.5.0(eslint@8.57.0)(typescript@5.4.4)
debug: 3.2.7
eslint: 9.0.0
eslint: 8.57.0
eslint-import-resolver-node: 0.3.9
transitivePeerDependencies:
- supports-color
dev: false
/eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.5.0)(eslint@9.0.0):
/eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.5.0)(eslint@8.57.0):
resolution: {integrity: sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==}
engines: {node: '>=4'}
peerDependencies:
@ -4560,16 +4571,16 @@ packages:
'@typescript-eslint/parser':
optional: true
dependencies:
'@typescript-eslint/parser': 7.5.0(eslint@9.0.0)(typescript@5.4.4)
'@typescript-eslint/parser': 7.5.0(eslint@8.57.0)(typescript@5.4.4)
array-includes: 3.1.7
array.prototype.findlastindex: 1.2.4
array.prototype.flat: 1.3.2
array.prototype.flatmap: 1.3.2
debug: 3.2.7
doctrine: 2.1.0
eslint: 9.0.0
eslint: 8.57.0
eslint-import-resolver-node: 0.3.9
eslint-module-utils: 2.8.0(@typescript-eslint/parser@7.5.0)(eslint-import-resolver-node@0.3.9)(eslint@9.0.0)
eslint-module-utils: 2.8.0(@typescript-eslint/parser@7.5.0)(eslint-import-resolver-node@0.3.9)(eslint@8.57.0)
hasown: 2.0.0
is-core-module: 2.13.1
is-glob: 4.0.3
@ -4585,7 +4596,7 @@ packages:
- supports-color
dev: false
/eslint-plugin-jsx-a11y@6.8.0(eslint@9.0.0):
/eslint-plugin-jsx-a11y@6.8.0(eslint@8.57.0):
resolution: {integrity: sha512-Hdh937BS3KdwwbBaKd5+PLCOmYY6U4f2h9Z2ktwtNKvIdIEu137rjYbcb9ApSbVJfWxANNuiKTD/9tOKjK9qOA==}
engines: {node: '>=4.0'}
peerDependencies:
@ -4601,7 +4612,7 @@ packages:
damerau-levenshtein: 1.0.8
emoji-regex: 9.2.2
es-iterator-helpers: 1.0.15
eslint: 9.0.0
eslint: 8.57.0
hasown: 2.0.0
jsx-ast-utils: 3.3.5
language-tags: 1.0.9
@ -4610,16 +4621,16 @@ packages:
object.fromentries: 2.0.7
dev: false
/eslint-plugin-react-hooks@4.6.0(eslint@9.0.0):
/eslint-plugin-react-hooks@4.6.0(eslint@8.57.0):
resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==}
engines: {node: '>=10'}
peerDependencies:
eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0
dependencies:
eslint: 9.0.0
eslint: 8.57.0
dev: false
/eslint-plugin-react@7.33.2(eslint@9.0.0):
/eslint-plugin-react@7.33.2(eslint@8.57.0):
resolution: {integrity: sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw==}
engines: {node: '>=4'}
peerDependencies:
@ -4630,7 +4641,7 @@ packages:
array.prototype.tosorted: 1.1.3
doctrine: 2.1.0
es-iterator-helpers: 1.0.15
eslint: 9.0.0
eslint: 8.57.0
estraverse: 5.3.0
jsx-ast-utils: 3.3.5
minimatch: 3.1.2
@ -4644,9 +4655,9 @@ packages:
string.prototype.matchall: 4.0.10
dev: false
/eslint-scope@8.0.1:
resolution: {integrity: sha512-pL8XjgP4ZOmmwfFE8mEhSxA7ZY4C+LWyqjQ3o4yWkkmD0qcMT9kkW3zWHOczhWcjTSgqycYAgwSlXvZltv65og==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
/eslint-scope@7.2.2:
resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dependencies:
esrecurse: 4.3.0
estraverse: 5.3.0
@ -4657,42 +4668,41 @@ packages:
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dev: false
/eslint-visitor-keys@4.0.0:
resolution: {integrity: sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
dev: false
/eslint@9.0.0:
resolution: {integrity: sha512-IMryZ5SudxzQvuod6rUdIUz29qFItWx281VhtFVc2Psy/ZhlCeD/5DT6lBIJ4H3G+iamGJoTln1v+QSuPw0p7Q==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
/eslint@8.57.0:
resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
hasBin: true
dependencies:
'@eslint-community/eslint-utils': 4.4.0(eslint@9.0.0)
'@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0)
'@eslint-community/regexpp': 4.10.0
'@eslint/eslintrc': 3.0.2
'@eslint/js': 9.0.0
'@humanwhocodes/config-array': 0.12.3
'@eslint/eslintrc': 2.1.4
'@eslint/js': 8.57.0
'@humanwhocodes/config-array': 0.11.14
'@humanwhocodes/module-importer': 1.0.1
'@nodelib/fs.walk': 1.2.8
'@ungap/structured-clone': 1.2.0
ajv: 6.12.6
chalk: 4.1.2
cross-spawn: 7.0.3
debug: 4.3.4
doctrine: 3.0.0
escape-string-regexp: 4.0.0
eslint-scope: 8.0.1
eslint-visitor-keys: 4.0.0
espree: 10.0.1
eslint-scope: 7.2.2
eslint-visitor-keys: 3.4.3
espree: 9.6.1
esquery: 1.5.0
esutils: 2.0.3
fast-deep-equal: 3.1.3
file-entry-cache: 8.0.0
file-entry-cache: 6.0.1
find-up: 5.0.0
glob-parent: 6.0.2
globals: 13.24.0
graphemer: 1.4.0
ignore: 5.3.1
imurmurhash: 0.1.4
is-glob: 4.0.3
is-path-inside: 3.0.3
js-yaml: 4.1.0
json-stable-stringify-without-jsonify: 1.0.1
levn: 0.4.1
lodash.merge: 4.6.2
@ -4705,13 +4715,13 @@ packages:
- supports-color
dev: false
/espree@10.0.1:
resolution: {integrity: sha512-MWkrWZbJsL2UwnjxTX3gG8FneachS/Mwg7tdGXce011sJd5b0JG54vat5KHnfSBODZ3Wvzd2WnjxyzsRoVv+ww==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
/espree@9.6.1:
resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dependencies:
acorn: 8.11.3
acorn-jsx: 5.3.2(acorn@8.11.3)
eslint-visitor-keys: 4.0.0
eslint-visitor-keys: 3.4.3
dev: false
/esprima@4.0.1:
@ -4841,11 +4851,11 @@ packages:
bser: 2.1.1
dev: false
/file-entry-cache@8.0.0:
resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==}
engines: {node: '>=16.0.0'}
/file-entry-cache@6.0.1:
resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==}
engines: {node: ^10.12.0 || >=12.0.0}
dependencies:
flat-cache: 4.0.1
flat-cache: 3.2.0
dev: false
/fill-range@7.0.1:
@ -4871,12 +4881,13 @@ packages:
path-exists: 4.0.0
dev: false
/flat-cache@4.0.1:
resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==}
engines: {node: '>=16'}
/flat-cache@3.2.0:
resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==}
engines: {node: ^10.12.0 || >=12.0.0}
dependencies:
flatted: 3.2.9
keyv: 4.5.4
rimraf: 3.0.2
dev: false
/flatted@3.2.9:
@ -5064,9 +5075,11 @@ packages:
engines: {node: '>=4'}
dev: false
/globals@14.0.0:
resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==}
engines: {node: '>=18'}
/globals@13.24.0:
resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==}
engines: {node: '>=8'}
dependencies:
type-fest: 0.20.2
dev: false
/globalthis@1.0.3:
@ -7135,6 +7148,13 @@ packages:
engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
dev: false
/rimraf@3.0.2:
resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==}
hasBin: true
dependencies:
glob: 7.2.3
dev: false
/run-parallel@1.2.0:
resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
dependencies:
@ -7741,6 +7761,11 @@ packages:
engines: {node: '>=4'}
dev: false
/type-fest@0.20.2:
resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==}
engines: {node: '>=10'}
dev: false
/type-fest@0.21.3:
resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==}
engines: {node: '>=10'}

View File

@ -12,6 +12,7 @@ interface Props extends HTMLProps<HTMLButtonElement> {
spinnerColor?: SpinnerColor
onFormStatusChange?: (pending: boolean) => void
onFormSubmitToastMessage?: string
primary?: boolean
}
export default function SubmitButtonWithStatus({
@ -23,6 +24,7 @@ export default function SubmitButtonWithStatus({
children,
disabled,
className,
primary,
type: _type,
...buttonProps
}: Props) {
@ -52,6 +54,7 @@ export default function SubmitButtonWithStatus({
className={clsx(
className,
'inline-flex items-center gap-2',
primary && 'primary',
styleAsLink && 'link',
)}
{...buttonProps}

View File

@ -218,7 +218,7 @@ export default function PhotoForm({
};
return (
<div className="space-y-8 max-w-[38rem]">
<div className="space-y-8 max-w-[38rem] relative">
{debugBlur && blurError &&
<div className="border error text-error rounded-md px-2 py-1">
{blurError}
@ -282,77 +282,86 @@ export default function PhotoForm({
<form
action={type === 'create' ? createPhotoAction : updatePhotoAction}
onSubmit={() => blur()}
className="space-y-6"
>
{FORM_METADATA_ENTRIES(
sortTagsObjectWithoutFavs(uniqueTags ?? [])
.map(({ tag, count }) => ({
value: tag,
annotation: formatCount(count),
annotationAria: formatCountDescriptive(count, 'tagged'),
})),
aiContent !== undefined,
)
.map(([key, {
label,
note,
required,
selectOptions,
selectOptionsDefaultLabel,
tagOptions,
readOnly,
validate,
validateStringMaxLength,
capitalize,
hideIfEmpty,
shouldHide,
loadingMessage,
type,
}]) =>
(
(!hideIfEmpty || formData[key]) &&
!shouldHide?.(formData)
) &&
<FieldSetWithStatus
key={key}
id={key}
label={label}
note={note}
error={formErrors[key]}
value={formData[key] ?? ''}
onChange={value => {
const formUpdated = { ...formData, [key]: value };
setFormData(formUpdated);
if (validate) {
setFormErrors({ ...formErrors, [key]: validate(value) });
} else if (validateStringMaxLength !== undefined) {
setFormErrors({
...formErrors,
[key]: value.length > validateStringMaxLength
? `${validateStringMaxLength} characters or less`
: undefined,
});
}
if (key === 'title') {
onTitleChange?.(value.trim());
}
}}
selectOptions={selectOptions}
selectOptionsDefaultLabel={selectOptionsDefaultLabel}
tagOptions={tagOptions}
required={required}
readOnly={readOnly}
capitalize={capitalize}
placeholder={loadingMessage && !formData[key]
? loadingMessage
: undefined}
loading={
(loadingMessage && !formData[key] ? true : false) ||
isFieldGeneratingAi(key)}
type={type}
accessory={aiButtonForField(key)}
/>)}
<div className="flex gap-3">
{/* Fields */}
<div className="space-y-6">
{FORM_METADATA_ENTRIES(
sortTagsObjectWithoutFavs(uniqueTags ?? [])
.map(({ tag, count }) => ({
value: tag,
annotation: formatCount(count),
annotationAria: formatCountDescriptive(count, 'tagged'),
})),
aiContent !== undefined,
)
.map(([key, {
label,
note,
required,
selectOptions,
selectOptionsDefaultLabel,
tagOptions,
readOnly,
validate,
validateStringMaxLength,
capitalize,
hideIfEmpty,
shouldHide,
loadingMessage,
type,
}]) =>
(
(!hideIfEmpty || formData[key]) &&
!shouldHide?.(formData)
) &&
<FieldSetWithStatus
key={key}
id={key}
label={label}
note={note}
error={formErrors[key]}
value={formData[key] ?? ''}
onChange={value => {
const formUpdated = { ...formData, [key]: value };
setFormData(formUpdated);
if (validate) {
setFormErrors({ ...formErrors, [key]: validate(value) });
} else if (validateStringMaxLength !== undefined) {
setFormErrors({
...formErrors,
[key]: value.length > validateStringMaxLength
? `${validateStringMaxLength} characters or less`
: undefined,
});
}
if (key === 'title') {
onTitleChange?.(value.trim());
}
}}
selectOptions={selectOptions}
selectOptionsDefaultLabel={selectOptionsDefaultLabel}
tagOptions={tagOptions}
required={required}
readOnly={readOnly}
capitalize={capitalize}
placeholder={loadingMessage && !formData[key]
? loadingMessage
: undefined}
loading={
(loadingMessage && !formData[key] ? true : false) ||
isFieldGeneratingAi(key)}
type={type}
accessory={aiButtonForField(key)}
/>)}
</div>
{/* Actions */}
<div className={clsx(
'flex gap-3 sticky bottom-0',
'pb-4 md:pb-8 pt-10',
'bg-gradient-to-t from-60% to-transparent',
'from-white/90',
'dark:from-black/95',
)}>
<Link
className="button"
href={type === 'edit' ? PATH_ADMIN_PHOTOS : PATH_ADMIN_UPLOADS}
@ -362,6 +371,7 @@ export default function PhotoForm({
<SubmitButtonWithStatus
disabled={!isFormValid(formData) || aiContent?.isLoading}
onFormStatusChange={onFormStatusChange}
primary
>
{type === 'create' ? 'Create' : 'Update'}
</SubmitButtonWithStatus>

View File

@ -123,7 +123,7 @@
}
.text-invert {
@apply
text-gray-100 dark:text-gray-900
text-white dark:text-black
}
.text-medium {
@apply