@@ -9,7 +9,6 @@ | |||||
"lint": "next lint" | "lint": "next lint" | ||||
}, | }, | ||||
"dependencies": { | "dependencies": { | ||||
"@reach/slider": "^0.18.0", | |||||
"@theoryofnekomata/formxtra": "^1.0.3", | "@theoryofnekomata/formxtra": "^1.0.3", | ||||
"@types/node": "20.3.1", | "@types/node": "20.3.1", | ||||
"@types/react": "18.2.14", | "@types/react": "18.2.14", | ||||
@@ -26,6 +25,7 @@ | |||||
"prismjs": "^1.29.0", | "prismjs": "^1.29.0", | ||||
"react": "18.2.0", | "react": "18.2.0", | ||||
"react-dom": "18.2.0", | "react-dom": "18.2.0", | ||||
"react-refractor": "^2.1.7", | |||||
"tailwindcss": "3.3.2", | "tailwindcss": "3.3.2", | ||||
"typescript": "5.1.3", | "typescript": "5.1.3", | ||||
"wavesurfer.js": "7.0.0-beta.11" | "wavesurfer.js": "7.0.0-beta.11" | ||||
@@ -1,13 +1,10 @@ | |||||
lockfileVersion: '6.1' | |||||
lockfileVersion: '6.0' | |||||
settings: | settings: | ||||
autoInstallPeers: true | autoInstallPeers: true | ||||
excludeLinksFromLockfile: false | excludeLinksFromLockfile: false | ||||
dependencies: | dependencies: | ||||
'@reach/slider': | |||||
specifier: ^0.18.0 | |||||
version: 0.18.0(react-dom@18.2.0)(react@18.2.0) | |||||
'@theoryofnekomata/formxtra': | '@theoryofnekomata/formxtra': | ||||
specifier: ^1.0.3 | specifier: ^1.0.3 | ||||
version: 1.0.3 | version: 1.0.3 | ||||
@@ -56,6 +53,9 @@ dependencies: | |||||
react-dom: | react-dom: | ||||
specifier: 18.2.0 | specifier: 18.2.0 | ||||
version: 18.2.0(react@18.2.0) | version: 18.2.0(react@18.2.0) | ||||
react-refractor: | |||||
specifier: ^2.1.7 | |||||
version: 2.1.7(react@18.2.0) | |||||
tailwindcss: | tailwindcss: | ||||
specifier: 3.3.2 | specifier: 3.3.2 | ||||
version: 3.3.2 | version: 3.3.2 | ||||
@@ -310,48 +310,6 @@ packages: | |||||
tslib: 2.5.3 | tslib: 2.5.3 | ||||
dev: false | dev: false | ||||
/@reach/auto-id@0.18.0(react-dom@18.2.0)(react@18.2.0): | |||||
resolution: {integrity: sha512-XwY1IwhM7mkHZFghhjiqjQ6dstbOdpbFLdggeke75u8/8icT8uEHLbovFUgzKjy9qPvYwZIB87rLiR8WdtOXCg==} | |||||
peerDependencies: | |||||
react: ^16.8.0 || 17.x | |||||
react-dom: ^16.8.0 || 17.x | |||||
dependencies: | |||||
'@reach/utils': 0.18.0(react-dom@18.2.0)(react@18.2.0) | |||||
react: 18.2.0 | |||||
react-dom: 18.2.0(react@18.2.0) | |||||
dev: false | |||||
/@reach/polymorphic@0.18.0(react@18.2.0): | |||||
resolution: {integrity: sha512-N9iAjdMbE//6rryZZxAPLRorzDcGBnluf7YQij6XDLiMtfCj1noa7KyLpEc/5XCIB/EwhX3zCluFAwloBKdblA==} | |||||
peerDependencies: | |||||
react: ^16.8.0 || 17.x | |||||
dependencies: | |||||
react: 18.2.0 | |||||
dev: false | |||||
/@reach/slider@0.18.0(react-dom@18.2.0)(react@18.2.0): | |||||
resolution: {integrity: sha512-DLq8ziZn74P/puY0F2tO7fR67PPp7/MIiydfvUdB3kefmn8ewXMUrY7tO6sdhVXk2y2Jtncd5PO1NStPn1QFfw==} | |||||
peerDependencies: | |||||
react: ^16.9.0 || 17.x | |||||
react-dom: ^16.9.0 || 17.x | |||||
dependencies: | |||||
'@reach/auto-id': 0.18.0(react-dom@18.2.0)(react@18.2.0) | |||||
'@reach/polymorphic': 0.18.0(react@18.2.0) | |||||
'@reach/utils': 0.18.0(react-dom@18.2.0)(react@18.2.0) | |||||
react: 18.2.0 | |||||
react-dom: 18.2.0(react@18.2.0) | |||||
dev: false | |||||
/@reach/utils@0.18.0(react-dom@18.2.0)(react@18.2.0): | |||||
resolution: {integrity: sha512-KdVMdpTgDyK8FzdKO9SCpiibuy/kbv3pwgfXshTI6tEcQT1OOwj7BAksnzGC0rPz0UholwC+AgkqEl3EJX3M1A==} | |||||
peerDependencies: | |||||
react: ^16.8.0 || 17.x | |||||
react-dom: ^16.8.0 || 17.x | |||||
dependencies: | |||||
react: 18.2.0 | |||||
react-dom: 18.2.0(react@18.2.0) | |||||
dev: false | |||||
/@rushstack/eslint-patch@1.3.2: | /@rushstack/eslint-patch@1.3.2: | ||||
resolution: {integrity: sha512-V+MvGwaHH03hYhY+k6Ef/xKd6RYlc4q8WBx+2ANmipHJcKuktNcI/NgEsJgdSUF6Lw32njT6OnrRsKYCdgHjYw==} | resolution: {integrity: sha512-V+MvGwaHH03hYhY+k6Ef/xKd6RYlc4q8WBx+2ANmipHJcKuktNcI/NgEsJgdSUF6Lw32njT6OnrRsKYCdgHjYw==} | ||||
dev: false | dev: false | ||||
@@ -371,6 +329,12 @@ packages: | |||||
resolution: {integrity: sha512-epMsEE85fi4lfmJUH/89/iV/LI+F5CvNIvmgs5g5jYFPfhO2S/ae8WSsLOKWdwtoaZw9Q2IhJ4tQ5tFCcS/4HA==} | resolution: {integrity: sha512-epMsEE85fi4lfmJUH/89/iV/LI+F5CvNIvmgs5g5jYFPfhO2S/ae8WSsLOKWdwtoaZw9Q2IhJ4tQ5tFCcS/4HA==} | ||||
dev: true | dev: true | ||||
/@types/hast@2.3.4: | |||||
resolution: {integrity: sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==} | |||||
dependencies: | |||||
'@types/unist': 2.0.6 | |||||
dev: false | |||||
/@types/json5@0.0.29: | /@types/json5@0.0.29: | ||||
resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} | resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} | ||||
dev: false | dev: false | ||||
@@ -409,6 +373,10 @@ packages: | |||||
resolution: {integrity: sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==} | resolution: {integrity: sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==} | ||||
dev: false | dev: false | ||||
/@types/unist@2.0.6: | |||||
resolution: {integrity: sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==} | |||||
dev: false | |||||
/@types/wavesurfer.js@6.0.6: | /@types/wavesurfer.js@6.0.6: | ||||
resolution: {integrity: sha512-fD54o0RXZXxkOb+69Rt6rGViaHpIc1Mmde2aOX9qPhlQhrCPepybGnsekiG407+7scPlaK+hmuPez5AnnmlzGg==} | resolution: {integrity: sha512-fD54o0RXZXxkOb+69Rt6rGViaHpIc1Mmde2aOX9qPhlQhrCPepybGnsekiG407+7scPlaK+hmuPez5AnnmlzGg==} | ||||
dependencies: | dependencies: | ||||
@@ -749,6 +717,18 @@ packages: | |||||
supports-color: 7.2.0 | supports-color: 7.2.0 | ||||
dev: false | dev: false | ||||
/character-entities-legacy@1.1.4: | |||||
resolution: {integrity: sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==} | |||||
dev: false | |||||
/character-entities@1.2.4: | |||||
resolution: {integrity: sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==} | |||||
dev: false | |||||
/character-reference-invalid@1.1.4: | |||||
resolution: {integrity: sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==} | |||||
dev: false | |||||
/chokidar@3.5.3: | /chokidar@3.5.3: | ||||
resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} | resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} | ||||
engines: {node: '>= 8.10.0'} | engines: {node: '>= 8.10.0'} | ||||
@@ -798,6 +778,10 @@ packages: | |||||
delayed-stream: 1.0.0 | delayed-stream: 1.0.0 | ||||
dev: false | dev: false | ||||
/comma-separated-tokens@1.0.8: | |||||
resolution: {integrity: sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==} | |||||
dev: false | |||||
/commander@4.1.1: | /commander@4.1.1: | ||||
resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} | resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} | ||||
engines: {node: '>= 6'} | engines: {node: '>= 6'} | ||||
@@ -1679,6 +1663,20 @@ packages: | |||||
function-bind: 1.1.1 | function-bind: 1.1.1 | ||||
dev: false | dev: false | ||||
/hast-util-parse-selector@2.2.5: | |||||
resolution: {integrity: sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==} | |||||
dev: false | |||||
/hastscript@6.0.0: | |||||
resolution: {integrity: sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==} | |||||
dependencies: | |||||
'@types/hast': 2.3.4 | |||||
comma-separated-tokens: 1.0.8 | |||||
hast-util-parse-selector: 2.2.5 | |||||
property-information: 5.6.0 | |||||
space-separated-tokens: 1.1.5 | |||||
dev: false | |||||
/http-signature@1.2.0: | /http-signature@1.2.0: | ||||
resolution: {integrity: sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==} | resolution: {integrity: sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==} | ||||
engines: {node: '>=0.8', npm: '>=1.3.7'} | engines: {node: '>=0.8', npm: '>=1.3.7'} | ||||
@@ -1740,6 +1738,17 @@ packages: | |||||
resolution: {integrity: sha512-pZ2xT+LOHckCatGQ3DcG/a+QuEqvoxqkiL7tvE8nn3uuu+f6i1TtpB5/FtWFbxUuVr5PZCx8KskuGatbJDXOWA==} | resolution: {integrity: sha512-pZ2xT+LOHckCatGQ3DcG/a+QuEqvoxqkiL7tvE8nn3uuu+f6i1TtpB5/FtWFbxUuVr5PZCx8KskuGatbJDXOWA==} | ||||
dev: false | dev: false | ||||
/is-alphabetical@1.0.4: | |||||
resolution: {integrity: sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==} | |||||
dev: false | |||||
/is-alphanumerical@1.0.4: | |||||
resolution: {integrity: sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==} | |||||
dependencies: | |||||
is-alphabetical: 1.0.4 | |||||
is-decimal: 1.0.4 | |||||
dev: false | |||||
/is-array-buffer@3.0.2: | /is-array-buffer@3.0.2: | ||||
resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==} | resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==} | ||||
dependencies: | dependencies: | ||||
@@ -1791,6 +1800,10 @@ packages: | |||||
has-tostringtag: 1.0.0 | has-tostringtag: 1.0.0 | ||||
dev: false | dev: false | ||||
/is-decimal@1.0.4: | |||||
resolution: {integrity: sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==} | |||||
dev: false | |||||
/is-docker@2.2.1: | /is-docker@2.2.1: | ||||
resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} | resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} | ||||
engines: {node: '>=8'} | engines: {node: '>=8'} | ||||
@@ -1815,6 +1828,10 @@ packages: | |||||
is-extglob: 2.1.1 | is-extglob: 2.1.1 | ||||
dev: false | dev: false | ||||
/is-hexadecimal@1.0.4: | |||||
resolution: {integrity: sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==} | |||||
dev: false | |||||
/is-inside-container@1.0.0: | /is-inside-container@1.0.0: | ||||
resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} | resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} | ||||
engines: {node: '>=14.16'} | engines: {node: '>=14.16'} | ||||
@@ -2346,6 +2363,17 @@ packages: | |||||
data-uri-to-buffer: 0.0.3 | data-uri-to-buffer: 0.0.3 | ||||
dev: false | dev: false | ||||
/parse-entities@2.0.0: | |||||
resolution: {integrity: sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==} | |||||
dependencies: | |||||
character-entities: 1.2.4 | |||||
character-entities-legacy: 1.1.4 | |||||
character-reference-invalid: 1.1.4 | |||||
is-alphanumerical: 1.0.4 | |||||
is-decimal: 1.0.4 | |||||
is-hexadecimal: 1.0.4 | |||||
dev: false | |||||
/path-exists@4.0.0: | /path-exists@4.0.0: | ||||
resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} | resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} | ||||
engines: {node: '>=8'} | engines: {node: '>=8'} | ||||
@@ -2487,6 +2515,11 @@ packages: | |||||
engines: {node: '>= 0.8.0'} | engines: {node: '>= 0.8.0'} | ||||
dev: false | dev: false | ||||
/prismjs@1.27.0: | |||||
resolution: {integrity: sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==} | |||||
engines: {node: '>=6'} | |||||
dev: false | |||||
/prismjs@1.29.0: | /prismjs@1.29.0: | ||||
resolution: {integrity: sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==} | resolution: {integrity: sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==} | ||||
engines: {node: '>=6'} | engines: {node: '>=6'} | ||||
@@ -2500,6 +2533,12 @@ packages: | |||||
react-is: 16.13.1 | react-is: 16.13.1 | ||||
dev: false | dev: false | ||||
/property-information@5.6.0: | |||||
resolution: {integrity: sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==} | |||||
dependencies: | |||||
xtend: 4.0.2 | |||||
dev: false | |||||
/psl@1.9.0: | /psl@1.9.0: | ||||
resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} | resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} | ||||
dev: false | dev: false | ||||
@@ -2532,6 +2571,18 @@ packages: | |||||
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} | resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} | ||||
dev: false | dev: false | ||||
/react-refractor@2.1.7(react@18.2.0): | |||||
resolution: {integrity: sha512-avNxSSsnjYg+BKpO8LVCK14KRn5pLZ+8DInMiUEeZPL6hs0SN0zafl3mJIxavGQPKyihqbXqzq4CYNflJQjaaw==} | |||||
peerDependencies: | |||||
react: '>=15.0.0' | |||||
dependencies: | |||||
prop-types: 15.8.1 | |||||
react: 18.2.0 | |||||
refractor: 3.6.0 | |||||
unist-util-filter: 2.0.3 | |||||
unist-util-visit-parents: 3.1.1 | |||||
dev: false | |||||
/react@18.2.0: | /react@18.2.0: | ||||
resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} | resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} | ||||
engines: {node: '>=0.10.0'} | engines: {node: '>=0.10.0'} | ||||
@@ -2552,6 +2603,14 @@ packages: | |||||
picomatch: 2.3.1 | picomatch: 2.3.1 | ||||
dev: false | dev: false | ||||
/refractor@3.6.0: | |||||
resolution: {integrity: sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA==} | |||||
dependencies: | |||||
hastscript: 6.0.0 | |||||
parse-entities: 2.0.0 | |||||
prismjs: 1.27.0 | |||||
dev: false | |||||
/regenerator-runtime@0.13.11: | /regenerator-runtime@0.13.11: | ||||
resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==} | resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==} | ||||
dev: false | dev: false | ||||
@@ -2718,6 +2777,10 @@ packages: | |||||
engines: {node: '>=0.10.0'} | engines: {node: '>=0.10.0'} | ||||
dev: false | dev: false | ||||
/space-separated-tokens@1.1.5: | |||||
resolution: {integrity: sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==} | |||||
dev: false | |||||
/sshpk@1.17.0: | /sshpk@1.17.0: | ||||
resolution: {integrity: sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==} | resolution: {integrity: sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==} | ||||
engines: {node: '>=0.10.0'} | engines: {node: '>=0.10.0'} | ||||
@@ -3013,6 +3076,23 @@ packages: | |||||
resolution: {integrity: sha512-Gw+zz50YNKPDKXs+9d+aKAjVwpjNwqzvNpLigIruT4HA9lMZNdMqs9x07kKHB/L9WRzqp4+DlTU5s4wG2esdoA==} | resolution: {integrity: sha512-Gw+zz50YNKPDKXs+9d+aKAjVwpjNwqzvNpLigIruT4HA9lMZNdMqs9x07kKHB/L9WRzqp4+DlTU5s4wG2esdoA==} | ||||
dev: false | dev: false | ||||
/unist-util-filter@2.0.3: | |||||
resolution: {integrity: sha512-8k6Jl/KLFqIRTHydJlHh6+uFgqYHq66pV75pZgr1JwfyFSjbWb12yfb0yitW/0TbHXjr9U4G9BQpOvMANB+ExA==} | |||||
dependencies: | |||||
unist-util-is: 4.1.0 | |||||
dev: false | |||||
/unist-util-is@4.1.0: | |||||
resolution: {integrity: sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==} | |||||
dev: false | |||||
/unist-util-visit-parents@3.1.1: | |||||
resolution: {integrity: sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==} | |||||
dependencies: | |||||
'@types/unist': 2.0.6 | |||||
unist-util-is: 4.1.0 | |||||
dev: false | |||||
/untildify@4.0.0: | /untildify@4.0.0: | ||||
resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==} | resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==} | ||||
engines: {node: '>=8'} | engines: {node: '>=8'} | ||||
@@ -3105,6 +3185,11 @@ packages: | |||||
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} | resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} | ||||
dev: false | dev: false | ||||
/xtend@4.0.2: | |||||
resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} | |||||
engines: {node: '>=0.4'} | |||||
dev: false | |||||
/yallist@4.0.0: | /yallist@4.0.0: | ||||
resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} | resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} | ||||
dev: false | dev: false | ||||
@@ -1,5 +1,5 @@ | |||||
export interface SelectOption { | export interface SelectOption { | ||||
label: string; | label: string; | ||||
value?: string; | |||||
value?: string | number; | |||||
children?: SelectOption[]; | children?: SelectOption[]; | ||||
} | } |
@@ -291,22 +291,27 @@ export const AudioFilePreview = React.forwardRef<AudioFilePreviewDerivedComponen | |||||
onChange={setSeek} | onChange={setSeek} | ||||
defaultValue="0" | defaultValue="0" | ||||
step="any" | step="any" | ||||
length="100%" | |||||
/> | /> | ||||
</div> | </div> | ||||
<span className="tabular-nums font-bold"> | <span className="tabular-nums font-bold"> | ||||
{formatSecondsDurationConcise(durationDisplay)} | {formatSecondsDurationConcise(durationDisplay)} | ||||
</span> | </span> | ||||
</div> | </div> | ||||
<Slider | |||||
ref={volumeRef} | |||||
max={1} | |||||
min={0} | |||||
onChange={adjustVolume} | |||||
step="any" | |||||
<div | |||||
className="flex-shrink-0 w-12" | className="flex-shrink-0 w-12" | ||||
defaultValue="1" | |||||
title="Volume" | |||||
/> | |||||
> | |||||
<Slider | |||||
ref={volumeRef} | |||||
max={1} | |||||
min={0} | |||||
onChange={adjustVolume} | |||||
step="any" | |||||
defaultValue="1" | |||||
title="Volume" | |||||
length="100%" | |||||
/> | |||||
</div> | |||||
</div> | </div> | ||||
)} | )} | ||||
</div> | </div> | ||||
@@ -95,6 +95,22 @@ export const TextFilePreview = React.forwardRef<TextFilePreviewDerivedComponent, | |||||
children: formatFileSize(fileWithMetadata.size) || '(Loading)', | children: formatFileSize(fileWithMetadata.size) || '(Loading)', | ||||
}, | }, | ||||
}, | }, | ||||
typeof fileWithMetadata.metadata?.lineCount === 'number' | |||||
&& typeof fileWithMetadata.metadata?.linesOfCode !== 'number' | |||||
&& { | |||||
key: 'Lines', | |||||
valueProps: { | |||||
children: `${formatNumeral(fileWithMetadata.metadata.lineCount)} line(s)` | |||||
}, | |||||
}, | |||||
typeof fileWithMetadata.metadata?.lineCount === 'number' | |||||
&& typeof fileWithMetadata.metadata?.linesOfCode === 'number' | |||||
&& { | |||||
key: 'Lines', | |||||
valueProps: { | |||||
children: `${formatNumeral(fileWithMetadata.metadata.lineCount)} line(s), ${formatNumeral(fileWithMetadata.metadata.linesOfCode)} loc`, | |||||
}, | |||||
}, | |||||
Array.isArray(fileWithMetadata.metadata?.languageMatches) | Array.isArray(fileWithMetadata.metadata?.languageMatches) | ||||
&& { | && { | ||||
key: 'Language', | key: 'Language', | ||||
@@ -111,7 +127,9 @@ export const TextFilePreview = React.forwardRef<TextFilePreviewDerivedComponent, | |||||
{language.slice(1)} | {language.slice(1)} | ||||
</dt> | </dt> | ||||
<dd className="tabular-nums"> | <dd className="tabular-nums"> | ||||
({(probability * 100).toFixed(3)}%) | |||||
{(probability * 100).toFixed(3)}% | |||||
{' '} | |||||
<abbr title="probability">prob.</abbr> | |||||
</dd> | </dd> | ||||
</div> | </div> | ||||
); | ); | ||||
@@ -120,22 +138,6 @@ export const TextFilePreview = React.forwardRef<TextFilePreviewDerivedComponent, | |||||
), | ), | ||||
}, | }, | ||||
}, | }, | ||||
typeof fileWithMetadata.metadata?.lineCount === 'number' | |||||
&& typeof fileWithMetadata.metadata?.linesOfCode !== 'number' | |||||
&& { | |||||
key: 'Lines', | |||||
valueProps: { | |||||
children: `${formatNumeral(fileWithMetadata.metadata.lineCount)} line(s)` | |||||
}, | |||||
}, | |||||
typeof fileWithMetadata.metadata?.lineCount === 'number' | |||||
&& typeof fileWithMetadata.metadata?.linesOfCode === 'number' | |||||
&& { | |||||
key: 'Lines', | |||||
valueProps: { | |||||
children: `${formatNumeral(fileWithMetadata.metadata.lineCount)} line(s), ${formatNumeral(fileWithMetadata.metadata.linesOfCode)} loc`, | |||||
}, | |||||
}, | |||||
]} | ]} | ||||
/> | /> | ||||
</div> | </div> | ||||
@@ -200,22 +200,27 @@ export const VideoFilePreview = React.forwardRef<VideoFilePreviewDerivedComponen | |||||
onChange={setSeek} | onChange={setSeek} | ||||
defaultValue="0" | defaultValue="0" | ||||
step="any" | step="any" | ||||
length="100%" | |||||
/> | /> | ||||
</div> | </div> | ||||
<span className="tabular-nums font-bold"> | <span className="tabular-nums font-bold"> | ||||
{formatSecondsDurationConcise(durationDisplay)} | {formatSecondsDurationConcise(durationDisplay)} | ||||
</span> | </span> | ||||
</div> | </div> | ||||
<Slider | |||||
ref={volumeRef} | |||||
max={1} | |||||
min={0} | |||||
onChange={adjustVolume} | |||||
step="any" | |||||
<div | |||||
className="flex-shrink-0 w-12" | className="flex-shrink-0 w-12" | ||||
defaultValue="1" | |||||
title="Volume" | |||||
/> | |||||
> | |||||
<Slider | |||||
ref={volumeRef} | |||||
max={1} | |||||
min={0} | |||||
onChange={adjustVolume} | |||||
step="any" | |||||
defaultValue="1" | |||||
title="Volume" | |||||
length="100%" | |||||
/> | |||||
</div> | |||||
</div> | </div> | ||||
)} | )} | ||||
</div> | </div> | ||||
@@ -1,37 +1,207 @@ | |||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import clsx from 'clsx'; | import clsx from 'clsx'; | ||||
import {slider} from './style.module.css'; | import {slider} from './style.module.css'; | ||||
import * as SelectControlBase from '@tesseract-design/web-base-selectcontrol'; | |||||
type SliderDerivedComponent = HTMLInputElement; | |||||
type SliderOrientation = 'horizontal' | 'vertical'; | |||||
export interface SliderProps extends Omit<React.HTMLProps<HTMLInputElement>, 'type'> { | |||||
interface RenderOptionsProps { | |||||
options: (number | SelectControlBase.SelectOption)[], | |||||
optionComponent?: React.ElementType, | |||||
optgroupComponent?: React.ElementType, | |||||
level?: number, | |||||
} | |||||
const RenderOptions: React.FC<RenderOptionsProps> = ({ | |||||
options, | |||||
optionComponent: Option = 'option', | |||||
optgroupComponent: Optgroup = 'optgroup', | |||||
level = 0, | |||||
}: RenderOptionsProps) => ( | |||||
<> | |||||
{ | |||||
options.map((o) => { | |||||
if (typeof o === 'number') { | |||||
return ( | |||||
<Option | |||||
key={`${o}:${o}`} | |||||
value={o} | |||||
/> | |||||
) | |||||
} | |||||
if (typeof o.value !== 'undefined') { | |||||
return ( | |||||
<Option | |||||
key={`${o.label}:${o.value.toString()}`} | |||||
value={o.value} | |||||
label={o.label} | |||||
> | |||||
{o.label} | |||||
</Option> | |||||
); | |||||
} | |||||
if (typeof o.children !== 'undefined') { | |||||
if (level === 0) { | |||||
return ( | |||||
<Optgroup | |||||
key={o.label} | |||||
label={o.label} | |||||
> | |||||
<RenderOptions | |||||
options={o.children} | |||||
optionComponent={Option} | |||||
optgroupComponent={Optgroup} | |||||
level={level + 1} | |||||
/> | |||||
</Optgroup> | |||||
); | |||||
} | |||||
return ( | |||||
<React.Fragment | |||||
key={o.label} | |||||
> | |||||
<Option | |||||
disabled | |||||
> | |||||
{o.label} | |||||
</Option> | |||||
<RenderOptions | |||||
options={o.children} | |||||
optionComponent={Option} | |||||
optgroupComponent={Optgroup} | |||||
level={level + 1} | |||||
/> | |||||
</React.Fragment> | |||||
); | |||||
} | |||||
return null; | |||||
}) | |||||
} | |||||
</> | |||||
); | |||||
type SliderDerivedElement = HTMLInputElement; | |||||
export interface SliderProps extends Omit<React.HTMLProps<HTMLInputElement>, 'type'> { | |||||
orient?: SliderOrientation; | |||||
tickMarks?: (number | SelectControlBase.SelectOption)[]; | |||||
length?: React.CSSProperties['width']; | |||||
} | } | ||||
export const Slider = React.forwardRef<SliderDerivedComponent, SliderProps>(({ | |||||
export const Slider = React.forwardRef<SliderDerivedElement, SliderProps>(({ | |||||
className, | className, | ||||
style, | style, | ||||
tickMarks = [], | |||||
orient = 'horizontal', | |||||
length, | |||||
...etcProps | ...etcProps | ||||
}, forwardedRef) => { | }, forwardedRef) => { | ||||
const [browser, setBrowser] = React.useState<string>(); | |||||
React.useEffect(() => { | |||||
const isFirefox = typeof (window as unknown as Record<string, unknown>).InstallTrigger !== 'undefined'; | |||||
if (isFirefox) { | |||||
setBrowser('firefox'); | |||||
} | |||||
}, []); | |||||
const defaultRef = React.useRef<HTMLInputElement>(null); | |||||
const ref = forwardedRef ?? defaultRef; | |||||
const tickMarkId = React.useId(); | |||||
React.useEffect(() => { | |||||
if (!(typeof ref === 'object' && ref.current)) { | |||||
return; | |||||
} | |||||
const {current: slider} = ref; | |||||
const isFirefox = browser === 'firefox'; | |||||
if (isFirefox) { | |||||
slider.setAttribute('orient', orient); | |||||
slider.removeAttribute('data-orient'); | |||||
} | |||||
return () => { | |||||
if (slider && isFirefox) { | |||||
slider.dataset.orient = slider.getAttribute(orient) ?? undefined; | |||||
slider.removeAttribute('orient'); | |||||
} | |||||
}; | |||||
}, [ref, orient, browser]); | |||||
React.useEffect(() => { | |||||
if (!(typeof ref === 'object' && ref.current)) { | |||||
return; | |||||
} | |||||
const {current: slider} = ref; | |||||
const isNotFirefox = browser !== 'firefox'; | |||||
if (isNotFirefox && orient === 'vertical' && slider) { | |||||
const parent = slider.parentElement as HTMLElement; | |||||
const grandParent = parent.parentElement as HTMLElement; | |||||
const trueHeight = slider!.parentElement!.clientWidth; | |||||
const trueWidth = slider!.parentElement!.clientHeight; | |||||
grandParent.style.height = trueHeight + 'px'; | |||||
grandParent.style.width = trueWidth + 'px'; | |||||
} | |||||
return () => { | |||||
if (slider && isNotFirefox) { | |||||
} | |||||
}; | |||||
}, [ref, orient, browser]); | |||||
const block = typeof length === 'string' && length.trim() === '100%'; | |||||
return ( | return ( | ||||
<div | |||||
className={clsx( | |||||
className, | |||||
)} | |||||
style={style} | |||||
> | |||||
<input | |||||
{...etcProps} | |||||
ref={forwardedRef} | |||||
type="range" | |||||
<> | |||||
{ | |||||
tickMarks.length > 0 | |||||
&& ( | |||||
<datalist | |||||
id={tickMarkId} | |||||
> | |||||
<RenderOptions | |||||
options={tickMarks} | |||||
/> | |||||
</datalist> | |||||
) | |||||
} | |||||
<div | |||||
className={clsx( | className={clsx( | ||||
slider, | |||||
'w-full h-full bg-inherit slider block text-primary ring-secondary/50 rounded-full', | |||||
'focus:text-secondary focus:outline-0 focus:ring-4', | |||||
'active:text-tertiary active:ring-tertiary/50', | |||||
block && orient !== 'vertical' && 'w-full', | |||||
!block && 'align-middle', | |||||
className, | |||||
orient !== 'vertical' && 'inline-block min-w-[16rem] min-h-[1rem]', | |||||
orient === 'vertical' && 'inline-block min-w-[1rem]', | |||||
//orient === 'vertical' && 'inline-block min-h-[16rem] min-w-[1rem]', | |||||
)} | )} | ||||
/> | |||||
</div> | |||||
style={style} | |||||
> | |||||
<div | |||||
style={{ | |||||
width: orient === 'vertical' ? (length ?? '16rem') : undefined, | |||||
position: 'relative', | |||||
}} | |||||
> | |||||
<input | |||||
{...etcProps} | |||||
ref={ref} | |||||
type="range" | |||||
data-orient={orient} | |||||
className={clsx( | |||||
slider, | |||||
'w-full h-full bg-inherit block text-primary ring-secondary/50 rounded-full', | |||||
'focus:text-secondary focus:outline-0 focus:ring-4', | |||||
'active:text-tertiary active:ring-tertiary/50', | |||||
)} | |||||
/> | |||||
</div> | |||||
</div> | |||||
</> | |||||
) | ) | ||||
}); | }); | ||||
@@ -7,19 +7,8 @@ | |||||
color: rgb(var(--color-primary)); | color: rgb(var(--color-primary)); | ||||
} | } | ||||
.slider::before { | |||||
border-radius: 9999px; | |||||
content: ''; | |||||
display: block; | |||||
position: absolute; | |||||
background-color: currentColor; | |||||
opacity: 0.5; | |||||
width: 100%; | |||||
height: 50%; | |||||
top: 25%; | |||||
} | |||||
.slider::-webkit-slider-container { | .slider::-webkit-slider-container { | ||||
width: 100%; | |||||
height: 100%; | height: 100%; | ||||
overflow: hidden; | overflow: hidden; | ||||
box-sizing: border-box; | box-sizing: border-box; | ||||
@@ -27,7 +16,14 @@ | |||||
.slider::-webkit-slider-runnable-track { | .slider::-webkit-slider-runnable-track { | ||||
appearance: none; | appearance: none; | ||||
height: 100%; | |||||
border-radius: 9999px; | |||||
content: ''; | |||||
display: block; | |||||
position: absolute; | |||||
background-color: rgb(var(--color-primary) / 50%); | |||||
width: 100%; | |||||
height: 50%; | |||||
top: 25%; | |||||
} | } | ||||
.slider::-moz-range-track { | .slider::-moz-range-track { | ||||
@@ -44,11 +40,13 @@ | |||||
} | } | ||||
.slider::-webkit-slider-thumb { | .slider::-webkit-slider-thumb { | ||||
margin-top: -0.25em; | |||||
width: 1em; | |||||
height: 200%; | |||||
border-radius: 9999px; | border-radius: 9999px; | ||||
background-color: currentColor; | background-color: currentColor; | ||||
appearance: none; | appearance: none; | ||||
width: 1em; | |||||
height: 100%; | |||||
aspect-ratio: 1 / 1; | aspect-ratio: 1 / 1; | ||||
z-index: 1; | z-index: 1; | ||||
position: relative; | position: relative; | ||||
@@ -56,16 +54,25 @@ | |||||
} | } | ||||
.slider::-moz-range-thumb { | .slider::-moz-range-thumb { | ||||
height: 100%; | |||||
outline: 0; | |||||
border: 0; | |||||
border-radius: 9999px; | border-radius: 9999px; | ||||
background-color: currentColor; | background-color: currentColor; | ||||
appearance: none; | appearance: none; | ||||
height: 100%; | |||||
aspect-ratio: 1 / 1; | aspect-ratio: 1 / 1; | ||||
z-index: 1; | z-index: 1; | ||||
position: relative; | position: relative; | ||||
box-shadow: -100000.5em 0 0 100000em rgb(var(--color-primary) / 50%); | box-shadow: -100000.5em 0 0 100000em rgb(var(--color-primary) / 50%); | ||||
outline: 0; | |||||
border: 0; | |||||
} | |||||
.slider:focus::-webkit-slider-runnable-track { | |||||
background-color: rgb(var(--color-secondary) / 50%); | |||||
} | |||||
.slider:active::-webkit-slider-runnable-track { | |||||
background-color: rgb(var(--color-tertiary) / 50%); | |||||
} | } | ||||
.slider:focus::-webkit-slider-thumb { | .slider:focus::-webkit-slider-thumb { | ||||
@@ -83,3 +90,33 @@ | |||||
.slider:active::-moz-range-thumb { | .slider:active::-moz-range-thumb { | ||||
box-shadow: -100000.5em 0 0 100000em rgb(var(--color-tertiary) / 50%); | box-shadow: -100000.5em 0 0 100000em rgb(var(--color-tertiary) / 50%); | ||||
} | } | ||||
.slider[orient='vertical'] { | |||||
width: 1em; | |||||
height: 16em; | |||||
} | |||||
.slider[orient='vertical']::-moz-range-track { | |||||
width: 50%; | |||||
height: 100%; | |||||
} | |||||
.slider[orient='vertical']::-moz-range-thumb { | |||||
width: 100%; | |||||
height: 1em; | |||||
box-shadow: 0 100000.5em 0 100000em rgb(var(--color-primary) / 50%); | |||||
} | |||||
.slider[orient='vertical']:focus::-moz-range-thumb { | |||||
box-shadow: 0 100000.5em 0 100000em rgb(var(--color-secondary) / 50%); | |||||
} | |||||
.slider[orient='vertical']:active::-moz-range-thumb { | |||||
box-shadow: 0 100000.5em 0 100000em rgb(var(--color-tertiary) / 50%); | |||||
} | |||||
.slider[data-orient='vertical'] { | |||||
rotate: -90deg; | |||||
translate: calc(-100% + 0.5em * 2); | |||||
transform-origin: calc(100% - 0.5em) 0.5em; | |||||
} |
@@ -18,6 +18,7 @@ export const BinaryDataCanvas = React.forwardRef<BinaryDataCanvasDerivedElement, | |||||
byteClassName, | byteClassName, | ||||
headers = false, | headers = false, | ||||
className, | className, | ||||
style, | |||||
...etcProps | ...etcProps | ||||
}, forwardedRef) => { | }, forwardedRef) => { | ||||
const bytesGrouped = arrayBuffer ? (Array.from(new Uint8Array(arrayBuffer)).slice(0, BYTES_PER_LINE * 20) as number[]) | const bytesGrouped = arrayBuffer ? (Array.from(new Uint8Array(arrayBuffer)).slice(0, BYTES_PER_LINE * 20) as number[]) | ||||
@@ -41,10 +42,17 @@ export const BinaryDataCanvas = React.forwardRef<BinaryDataCanvasDerivedElement, | |||||
) : [] as number[][]; | ) : [] as number[][]; | ||||
return ( | return ( | ||||
<div className={clsx( | |||||
'flex gap-2 leading-tight', | |||||
className, | |||||
)}> | |||||
<div | |||||
className={clsx( | |||||
className, | |||||
)} | |||||
style={{ | |||||
...(style ?? {}), | |||||
display: 'flex', | |||||
gap: '0.5rem', | |||||
alignItems: 'flex-start', | |||||
}} | |||||
> | |||||
{headers && ( | {headers && ( | ||||
<pre | <pre | ||||
style={{ | style={{ | ||||
@@ -75,7 +83,11 @@ export const BinaryDataCanvas = React.forwardRef<BinaryDataCanvasDerivedElement, | |||||
<pre | <pre | ||||
{...etcProps} | {...etcProps} | ||||
ref={forwardedRef} | ref={forwardedRef} | ||||
className="leading-tight" | |||||
style={{ | |||||
padding: 0, | |||||
overflow: 'visible', | |||||
margin: 0, | |||||
}} | |||||
> | > | ||||
<code> | <code> | ||||
{headers && new Array(BYTES_PER_LINE).fill(0).map((_, i) => ( | {headers && new Array(BYTES_PER_LINE).fill(0).map((_, i) => ( | ||||
@@ -1,5 +1,5 @@ | |||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import PrismJs from 'prismjs'; | |||||
import Refractor from 'react-refractor/all'; | |||||
import clsx from 'clsx'; | import clsx from 'clsx'; | ||||
type PrismDerivedElement = HTMLPreElement; | type PrismDerivedElement = HTMLPreElement; | ||||
@@ -24,52 +24,20 @@ export const Prism = React.forwardRef<PrismDerivedElement, PrismProps>(({ | |||||
}, forwardedRef) => { | }, forwardedRef) => { | ||||
const [highlightedCode, setHighlightedCode] = React.useState<string>(''); | const [highlightedCode, setHighlightedCode] = React.useState<string>(''); | ||||
React.useEffect(() => { | |||||
const loadHighlighter = async () => { | |||||
if (language !== 'plain') { | |||||
await import(`prismjs/components/prism-${language}`); | |||||
} | |||||
if (!code) { | |||||
setHighlightedCode(''); | |||||
return; | |||||
} | |||||
if (!Number.isFinite(maxLineNumber)) { | |||||
setHighlightedCode( | |||||
PrismJs.highlight( | |||||
code, | |||||
PrismJs.languages[language], | |||||
language, | |||||
) | |||||
) | |||||
return; | |||||
} | |||||
setHighlightedCode( | |||||
PrismJs.highlight( | |||||
code, | |||||
PrismJs.languages[language], | |||||
language, | |||||
).split('\n').slice(0, maxLineNumber).join('\n') | |||||
); | |||||
} | |||||
void loadHighlighter(); | |||||
}, [language, code, maxLineNumber]); | |||||
if (!code) { | if (!code) { | ||||
return null; | return null; | ||||
} | } | ||||
return ( | return ( | ||||
<div | <div | ||||
className={clsx( | className={clsx( | ||||
'flex gap-2 leading-tight', | |||||
'react-prism', | |||||
className, | className, | ||||
)} | )} | ||||
style={style} | |||||
style={{ | |||||
...(style ?? {}), | |||||
}} | |||||
> | > | ||||
{lineNumbers && ( | {lineNumbers && ( | ||||
<pre | <pre | ||||
@@ -77,55 +45,26 @@ export const Prism = React.forwardRef<PrismDerivedElement, PrismProps>(({ | |||||
padding: 0, | padding: 0, | ||||
overflow: 'visible', | overflow: 'visible', | ||||
margin: 0, | margin: 0, | ||||
lineHeight: 1.2, | |||||
textAlign: 'right', | textAlign: 'right', | ||||
}} | }} | ||||
> | > | ||||
{new Array(maxLineNumber).fill(0).map((_, i) => ( | |||||
<React.Fragment key={i}> | |||||
{i > 0 && '\n'} | |||||
<code | |||||
style={{ | |||||
whiteSpace: 'nowrap', | |||||
}} | |||||
> | |||||
<code> | |||||
{new Array(maxLineNumber).fill(0).map((_, i) => ( | |||||
<React.Fragment key={i}> | |||||
{i > 0 && '\n'} | |||||
{i + 1} | {i + 1} | ||||
</code> | |||||
</React.Fragment> | |||||
))} | |||||
</React.Fragment> | |||||
))} | |||||
</code> | |||||
</pre> | </pre> | ||||
)} | )} | ||||
<pre | |||||
<Refractor | |||||
{...etcProps} | {...etcProps} | ||||
ref={forwardedRef} | |||||
> | |||||
{ | |||||
language !== 'plain' | |||||
&& ( | |||||
<code | |||||
className="prism" | |||||
dangerouslySetInnerHTML={{ | |||||
__html: highlightedCode, | |||||
}} | |||||
style={{ | |||||
tabSize, | |||||
}} | |||||
/> | |||||
) | |||||
} | |||||
{ | |||||
language === 'plain' | |||||
&& ( | |||||
<code | |||||
className="prism" | |||||
style={{ | |||||
tabSize, | |||||
}} | |||||
> | |||||
{code} | |||||
</code> | |||||
) | |||||
} | |||||
</pre> | |||||
language={language} | |||||
value={code} | |||||
className="highlight" | |||||
/> | |||||
</div> | </div> | ||||
) | ) | ||||
}); | }); | ||||
@@ -1,232 +1,46 @@ | |||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { NextPage } from 'next'; | import { NextPage } from 'next'; | ||||
import * as ReachSlider from '@reach/slider'; | |||||
import '@reach/slider/styles.css'; | |||||
import {delegateTriggerChangeEvent} from '../../../utils/event'; | |||||
import * as SelectControlBase from '@tesseract-design/web-base-selectcontrol'; | |||||
interface RenderOptionsProps { | |||||
options: (number | SelectControlBase.SelectOption)[], | |||||
optionComponent?: React.ElementType, | |||||
optgroupComponent?: React.ElementType, | |||||
level?: number, | |||||
} | |||||
export enum SliderOrientation { | |||||
HORIZONTAL = 'horizontal', | |||||
VERTICAL = 'vertical', | |||||
} | |||||
export interface SliderProps extends Omit<React.HTMLProps<HTMLInputElement>, 'type' | 'min' | 'max' | 'list'> { | |||||
enhanced?: boolean; | |||||
orient?: SliderOrientation; | |||||
min?: number; | |||||
max?: number; | |||||
block?: boolean; | |||||
tickMarks?: (number | SelectControlBase.SelectOption)[]; | |||||
} | |||||
const RenderOptions: React.FC<RenderOptionsProps> = ({ | |||||
options, | |||||
optionComponent: Option = 'option', | |||||
optgroupComponent: Optgroup = 'optgroup', | |||||
level = 0, | |||||
}: RenderOptionsProps) => ( | |||||
<> | |||||
{ | |||||
options.map((o) => { | |||||
if (typeof o === 'number') { | |||||
return ( | |||||
<Option | |||||
key={`${o}:${o}`} | |||||
value={o} | |||||
/> | |||||
) | |||||
} | |||||
if (typeof o.value !== 'undefined') { | |||||
return ( | |||||
<Option | |||||
key={`${o.label}:${o.value.toString()}`} | |||||
value={o.value} | |||||
label={o.label} | |||||
> | |||||
{o.label} | |||||
</Option> | |||||
); | |||||
} | |||||
if (typeof o.children !== 'undefined') { | |||||
if (level === 0) { | |||||
return ( | |||||
<Optgroup | |||||
key={o.label} | |||||
label={o.label} | |||||
> | |||||
<RenderOptions | |||||
options={o.children} | |||||
optionComponent={Option} | |||||
optgroupComponent={Optgroup} | |||||
level={level + 1} | |||||
/> | |||||
</Optgroup> | |||||
); | |||||
} | |||||
return ( | |||||
<React.Fragment | |||||
key={o.label} | |||||
> | |||||
<Option | |||||
disabled | |||||
> | |||||
{o.label} | |||||
</Option> | |||||
<RenderOptions | |||||
options={o.children} | |||||
optionComponent={Option} | |||||
optgroupComponent={Optgroup} | |||||
level={level + 1} | |||||
/> | |||||
</React.Fragment> | |||||
); | |||||
} | |||||
return null; | |||||
}) | |||||
} | |||||
</> | |||||
); | |||||
export const Slider = React.forwardRef<HTMLInputElement, SliderProps>(({ | |||||
enhanced = false, | |||||
orient = SliderOrientation.HORIZONTAL, | |||||
min = 0, | |||||
max = 100, | |||||
step = 'any', | |||||
block = false, | |||||
tickMarks = [], | |||||
onChange, | |||||
...etcProps | |||||
}, forwardedRef) => { | |||||
const [renderEnhanced, setRenderEnhanced] = React.useState(false); | |||||
const defaultRef = React.useRef<HTMLInputElement>(null); | |||||
const ref = forwardedRef ?? defaultRef; | |||||
const nonStandardProps: any = { | |||||
// Gecko (Firefox) fallback | |||||
orient, | |||||
} | |||||
const tickMarkId = React.useId(); | |||||
React.useEffect(() => { | |||||
setRenderEnhanced(enhanced); | |||||
}, [enhanced]); | |||||
const handleEnhancedRangeChange = (newValue: number) => { | |||||
if (typeof ref === 'object' && ref.current) { | |||||
delegateTriggerChangeEvent(ref.current, newValue); | |||||
} | |||||
} | |||||
return ( | |||||
<> | |||||
{ | |||||
tickMarks.length > 0 | |||||
&& ( | |||||
<datalist | |||||
id={tickMarkId} | |||||
> | |||||
<RenderOptions | |||||
options={tickMarks} | |||||
/> | |||||
</datalist> | |||||
) | |||||
} | |||||
<div> | |||||
<input | |||||
{...etcProps} | |||||
{...nonStandardProps} | |||||
min={min} | |||||
max={max} | |||||
step={step ?? 'any'} | |||||
type="range" | |||||
className={`${renderEnhanced ? 'sr-only' : ''} ${block ? 'w-full' : ''}`} | |||||
ref={ref} | |||||
list={tickMarks.length > 0 ? tickMarkId : undefined} | |||||
onChange={onChange} | |||||
/> | |||||
{ | |||||
renderEnhanced | |||||
&& ( | |||||
<> | |||||
<ReachSlider.SliderInput | |||||
min={min} | |||||
max={max} | |||||
step={typeof step === 'number' ? step : Number.EPSILON} | |||||
orientation={orient === SliderOrientation.VERTICAL ? ReachSlider.SliderOrientation.Vertical : ReachSlider.SliderOrientation.Horizontal} | |||||
onChange={handleEnhancedRangeChange} | |||||
> | |||||
<ReachSlider.SliderTrack> | |||||
<ReachSlider.SliderRange /> | |||||
<RenderOptions options={tickMarks} optionComponent={ReachSlider.SliderMarker} optgroupComponent={React.Fragment} /> | |||||
<ReachSlider.SliderHandle /> | |||||
</ReachSlider.SliderTrack> | |||||
</ReachSlider.SliderInput> | |||||
</> | |||||
) | |||||
} | |||||
</div> | |||||
</> | |||||
); | |||||
}); | |||||
Slider.displayName = 'Slider'; | |||||
import {Slider} from '@/categories/number/react'; | |||||
import {Section, Subsection} from '@/components/Section'; | |||||
const NumberPage: NextPage = () => { | const NumberPage: NextPage = () => { | ||||
return ( | return ( | ||||
<main className="my-16 md:my-32"> | <main className="my-16 md:my-32"> | ||||
<section> | |||||
<div className="container mx-auto px-4"> | |||||
<h1> | |||||
Number | |||||
</h1> | |||||
<div> | |||||
<section> | |||||
<h2> | |||||
Spinner | |||||
</h2> | |||||
<div> | |||||
TODO | |||||
<input type="number" /> | |||||
</div> | |||||
</section> | |||||
<section> | |||||
<h2> | |||||
Slider | |||||
</h2> | |||||
<div> | |||||
<Slider | |||||
min={-100} | |||||
max={100} | |||||
tickMarks={[{ label: 'low', value: 25, }, 50]} | |||||
enhanced | |||||
onChange={(e) => console.log(e.currentTarget.value)} | |||||
/> | |||||
</div> | |||||
</section> | |||||
<section> | |||||
<h2> | |||||
Matrix | |||||
</h2> | |||||
<div> | |||||
TODO | |||||
<input type="range" /> | |||||
<input type="range" /> | |||||
</div> | |||||
</section> | |||||
</div> | |||||
<Section title="Spinner"> | |||||
<Subsection title="Default"> | |||||
TODO | |||||
<input type="number" /> | |||||
</Subsection> | |||||
</Section> | |||||
<Section title="Slider"> | |||||
<Subsection title="Default"> | |||||
<Slider | |||||
min={-100} | |||||
max={100} | |||||
tickMarks={[{ label: 'low', value: 25, }, 50]} | |||||
/> | |||||
</Subsection> | |||||
<Subsection title="Vertical"> | |||||
<Slider | |||||
min={-100} | |||||
max={100} | |||||
tickMarks={[{ label: 'low', value: 25, }, 50]} | |||||
orient="vertical" | |||||
/> | |||||
A | |||||
</Subsection> | |||||
</Section> | |||||
<Section title="Matrix"> | |||||
<h2> | |||||
Matrix | |||||
</h2> | |||||
<div> | |||||
TODO | |||||
<input type="range" /> | |||||
<input type="range" /> | |||||
</div> | </div> | ||||
</section> | |||||
</Section> | |||||
</main> | </main> | ||||
) | ) | ||||
} | } | ||||
@@ -27,19 +27,25 @@ | |||||
} | } | ||||
} | } | ||||
.prism .token.number { color: rgb(var(--color-code-number)); } | |||||
.prism .token.keyword { color: rgb(var(--color-code-keyword)); } | |||||
.prism .token.type { color: rgb(var(--color-code-type)); } | |||||
.prism .token.instance-attribute { color: rgb(var(--color-code-instance-attribute)); } | |||||
.prism .token.function { color: rgb(var(--color-code-function)); } | |||||
.prism .token.parameter { color: rgb(var(--color-code-parameter)); } | |||||
.prism .token.property { color: rgb(var(--color-code-property)); } | |||||
.prism .token.string { color: rgb(var(--color-code-string)); } | |||||
.prism .token.variable { color: rgb(var(--color-code-variable)); } | |||||
.prism .token.regexp { color: rgb(var(--color-code-regexp)); } | |||||
.prism .token.url { color: rgb(var(--color-code-url)); } | |||||
.prism .token.global { color: rgb(var(--color-code-global)); } | |||||
.prism .token.comment { opacity: 0.5; } | |||||
.react-prism { | |||||
display: flex; | |||||
gap: 0.5rem; | |||||
align-items: flex-start; | |||||
} | |||||
.react-prism .token.number { color: rgb(var(--color-code-number)); } | |||||
.react-prism .token.keyword { color: rgb(var(--color-code-keyword)); } | |||||
.react-prism .token.type { color: rgb(var(--color-code-type)); } | |||||
.react-prism .token.instance-attribute { color: rgb(var(--color-code-instance-attribute)); } | |||||
.react-prism .token.function { color: rgb(var(--color-code-function)); } | |||||
.react-prism .token.parameter { color: rgb(var(--color-code-parameter)); } | |||||
.react-prism .token.property { color: rgb(var(--color-code-property)); } | |||||
.react-prism .token.string { color: rgb(var(--color-code-string)); } | |||||
.react-prism .token.variable { color: rgb(var(--color-code-variable)); } | |||||
.react-prism .token.regexp { color: rgb(var(--color-code-regexp)); } | |||||
.react-prism .token.url { color: rgb(var(--color-code-url)); } | |||||
.react-prism .token.global { color: rgb(var(--color-code-global)); } | |||||
.react-prism .token.comment { opacity: 0.5; } | |||||
.binary-file-preview .x00 { color: rgb(var(--color-code-keyword)); } | .binary-file-preview .x00 { color: rgb(var(--color-code-keyword)); } | ||||
.binary-file-preview .x10 { color: rgb(var(--color-code-global)); } | .binary-file-preview .x10 { color: rgb(var(--color-code-global)); } | ||||