@next-degree/pickle-shared-js 0.10.8 → 0.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/dist/{company_service_sanity-Bedw6Mhk.d.cts → company_service_sanity-Br0R7m-A.d.cts} +114 -114
  2. package/dist/{company_service_sanity-BZtdt7Df.d.ts → company_service_sanity-DF01qvTz.d.ts} +114 -114
  3. package/dist/components/jobCard/JobLocation.cjs +88 -0
  4. package/dist/components/jobCard/JobLocation.cjs.map +1 -0
  5. package/dist/components/jobCard/JobLocation.d.cts +9 -0
  6. package/dist/components/jobCard/JobLocation.d.ts +9 -0
  7. package/dist/components/jobCard/JobLocation.js +53 -0
  8. package/dist/components/jobCard/JobLocation.js.map +1 -0
  9. package/dist/components/jobPost/JobDescription.cjs +3 -1
  10. package/dist/components/jobPost/JobDescription.cjs.map +1 -1
  11. package/dist/components/jobPost/JobDescription.js +3 -1
  12. package/dist/components/jobPost/JobDescription.js.map +1 -1
  13. package/dist/components/jobPost/JobPost.cjs +17 -13
  14. package/dist/components/jobPost/JobPost.cjs.map +1 -1
  15. package/dist/components/jobPost/JobPost.d.cts +1 -1
  16. package/dist/components/jobPost/JobPost.d.ts +1 -1
  17. package/dist/components/jobPost/JobPost.js +17 -13
  18. package/dist/components/jobPost/JobPost.js.map +1 -1
  19. package/dist/components/ui/Button.d.cts +1 -1
  20. package/dist/components/ui/Button.d.ts +1 -1
  21. package/dist/components/ui/Combobox.cjs +28 -19
  22. package/dist/components/ui/Combobox.cjs.map +1 -1
  23. package/dist/components/ui/Combobox.js +29 -20
  24. package/dist/components/ui/Combobox.js.map +1 -1
  25. package/dist/components/ui/DismissibleBanner.cjs +85 -0
  26. package/dist/components/ui/DismissibleBanner.cjs.map +1 -0
  27. package/dist/components/ui/DismissibleBanner.d.cts +11 -0
  28. package/dist/components/ui/DismissibleBanner.d.ts +11 -0
  29. package/dist/components/ui/DismissibleBanner.js +60 -0
  30. package/dist/components/ui/DismissibleBanner.js.map +1 -0
  31. package/dist/components/ui/ReadMore.cjs +3 -1
  32. package/dist/components/ui/ReadMore.cjs.map +1 -1
  33. package/dist/components/ui/ReadMore.js +3 -1
  34. package/dist/components/ui/ReadMore.js.map +1 -1
  35. package/dist/components/ui/StepTabs.cjs +32 -4
  36. package/dist/components/ui/StepTabs.cjs.map +1 -1
  37. package/dist/components/ui/StepTabs.d.cts +12 -3
  38. package/dist/components/ui/StepTabs.d.ts +12 -3
  39. package/dist/components/ui/StepTabs.js +32 -4
  40. package/dist/components/ui/StepTabs.js.map +1 -1
  41. package/dist/components/ui/buttonShadcn.d.cts +1 -1
  42. package/dist/components/ui/buttonShadcn.d.ts +1 -1
  43. package/dist/{displayText-CBIWVZVw.d.ts → displayText-C1DIK8hr.d.ts} +1 -1
  44. package/dist/{displayText-4cJ7-3Mw.d.cts → displayText-DzxDrQAT.d.cts} +1 -1
  45. package/dist/hooks/useDisplayText.d.cts +2 -2
  46. package/dist/hooks/useDisplayText.d.ts +2 -2
  47. package/dist/index.cjs +1240 -1127
  48. package/dist/index.cjs.map +1 -1
  49. package/dist/index.d.cts +8 -4
  50. package/dist/index.d.ts +8 -4
  51. package/dist/index.js +1375 -1265
  52. package/dist/index.js.map +1 -1
  53. package/dist/{job_posting_service_sanity-Kcoloigd.d.cts → job_posting_service_sanity-B7GvIdYQ.d.cts} +173 -173
  54. package/dist/{job_posting_service_sanity-fAGLW3rj.d.ts → job_posting_service_sanity-CfLaGMVK.d.ts} +173 -173
  55. package/dist/lib/locations.d.cts +1 -1
  56. package/dist/lib/locations.d.ts +1 -1
  57. package/dist/lib/mappings.d.cts +2 -2
  58. package/dist/lib/mappings.d.ts +2 -2
  59. package/dist/lib/salaryRange.cjs +14 -12
  60. package/dist/lib/salaryRange.cjs.map +1 -1
  61. package/dist/lib/salaryRange.d.cts +1 -1
  62. package/dist/lib/salaryRange.d.ts +1 -1
  63. package/dist/lib/salaryRange.js +14 -12
  64. package/dist/lib/salaryRange.js.map +1 -1
  65. package/dist/services/displayText.d.cts +2 -2
  66. package/dist/services/displayText.d.ts +2 -2
  67. package/dist/styles/globals.css +25 -0
  68. package/dist/styles/globals.css.map +1 -1
  69. package/dist/types/data/company_service_latest.d.cts +1 -1
  70. package/dist/types/data/company_service_latest.d.ts +1 -1
  71. package/dist/types/data/job_posting_service_latest.d.cts +1 -1
  72. package/dist/types/data/job_posting_service_latest.d.ts +1 -1
  73. package/dist/types/index.d.cts +4 -4
  74. package/dist/types/index.d.ts +4 -4
  75. package/dist/types/latest/company_service_latest.d.cts +1 -1
  76. package/dist/types/latest/company_service_latest.d.ts +1 -1
  77. package/dist/types/latest/custom/company_service_sanity.d.cts +2 -2
  78. package/dist/types/latest/custom/company_service_sanity.d.ts +2 -2
  79. package/dist/types/latest/custom/job_posting_service_sanity.d.cts +2 -2
  80. package/dist/types/latest/custom/job_posting_service_sanity.d.ts +2 -2
  81. package/dist/types/latest/job_posting_service_latest.d.cts +1 -1
  82. package/dist/types/latest/job_posting_service_latest.d.ts +1 -1
  83. package/package.json +2 -2
  84. package/dist/{company_service_latest-BmiEQ4dO.d.cts → company_service_latest-C7Moeufo.d.cts} +54 -54
  85. package/dist/{company_service_latest-BmiEQ4dO.d.ts → company_service_latest-C7Moeufo.d.ts} +54 -54
  86. package/dist/{company_service_latest-Ba8VhDao.d.cts → company_service_latest-CITz7F53.d.cts} +54 -54
  87. package/dist/{company_service_latest-Ba8VhDao.d.ts → company_service_latest-CITz7F53.d.ts} +54 -54
  88. package/dist/{job_posting_service_latest-DdsTbMSJ.d.cts → job_posting_service_latest-DCbi2bXu.d.cts} +85 -85
  89. package/dist/{job_posting_service_latest-DdsTbMSJ.d.ts → job_posting_service_latest-DCbi2bXu.d.ts} +85 -85
  90. package/dist/{job_posting_service_latest-DOGQ9tEu.d.cts → job_posting_service_latest-tqnHqjwc.d.cts} +85 -85
  91. package/dist/{job_posting_service_latest-DOGQ9tEu.d.ts → job_posting_service_latest-tqnHqjwc.d.ts} +85 -85
@@ -162,6 +162,7 @@ var import_jsx_runtime2 = require("react/jsx-runtime");
162
162
  function ReadMore({ text, ...props }) {
163
163
  const [isExpanded, setIsExpanded] = (0, import_react2.useState)(false);
164
164
  const [maxWords, setMaxWords] = (0, import_react2.useState)(160);
165
+ const isOverMaxWords = text.split(" ").length > maxWords;
165
166
  (0, import_react2.useEffect)(() => {
166
167
  const updateMaxWords = () => {
167
168
  const windowWidth = window.innerWidth;
@@ -176,6 +177,7 @@ function ReadMore({ text, ...props }) {
176
177
  return () => window.removeEventListener("resize", updateMaxWords);
177
178
  }, []);
178
179
  function createReadMoreText(text2, maxWords2, isExpanded2) {
180
+ if (!isOverMaxWords) return text2;
179
181
  const words = text2.split(" ");
180
182
  const snippet2 = isExpanded2 ? text2 : words.slice(0, maxWords2).join(" ");
181
183
  const readMoreText = isExpanded2 ? "" : "...";
@@ -185,7 +187,7 @@ function ReadMore({ text, ...props }) {
185
187
  const snippet = createReadMoreText(text, maxWords, isExpanded);
186
188
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { ...props, children: [
187
189
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { "data-testid": "read-more-text", className: "prose lg:prose-lg", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_markdown.default, { children: snippet }) }),
188
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
190
+ isOverMaxWords && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
189
191
  Button,
190
192
  {
191
193
  type: "button",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/jobPost/JobDescription.tsx","../../../src/components/ui/ReadMore.tsx","../../../src/components/ui/Button.tsx","../../../src/lib/utils.ts"],"sourcesContent":["import { ReadMore } from '@/components/ui/ReadMore'\n\nexport type JobDescriptionProps = {\n description?: string\n}\n\nexport function JobDescription({ description }: JobDescriptionProps) {\n if (!description) return null\n\n return (\n <div className=\"flex w-full flex-col gap-2\">\n <h3 className=\"text-xl font-bold\">Job Description</h3>\n <ReadMore text={description} />\n </div>\n )\n}\n","'use client'\n\nimport { type ComponentProps, useEffect, useState } from 'react'\nimport Markdown from 'react-markdown'\n\nimport { Button } from '@/components/ui/Button'\n\nexport type ReadMoreProps = ComponentProps<'div'> & {\n text: string\n}\n\nexport function ReadMore({ text, ...props }: Readonly<ReadMoreProps>) {\n const [isExpanded, setIsExpanded] = useState(false)\n const [maxWords, setMaxWords] = useState(160)\n\n useEffect(() => {\n const updateMaxWords = () => {\n const windowWidth = window.innerWidth\n if (windowWidth <= 768) {\n setMaxWords(50)\n } else {\n setMaxWords(160)\n }\n }\n\n updateMaxWords()\n window.addEventListener('resize', updateMaxWords)\n\n return () => window.removeEventListener('resize', updateMaxWords)\n }, [])\n\n function createReadMoreText(text: string, maxWords: number, isExpanded: boolean): string {\n const words = text.split(' ')\n\n const snippet = isExpanded ? text : words.slice(0, maxWords).join(' ')\n const readMoreText = isExpanded ? '' : '...'\n return `${snippet} ${readMoreText}`\n }\n\n const toggleText = () => setIsExpanded(!isExpanded)\n\n const snippet = createReadMoreText(text, maxWords, isExpanded)\n\n return (\n <div {...props}>\n <div data-testid=\"read-more-text\" className=\"prose lg:prose-lg\">\n <Markdown>{snippet}</Markdown>\n </div>\n <Button\n type=\"button\"\n className=\"mt-2 flex items-center justify-center\"\n variant=\"link\"\n onClick={toggleText}\n >\n <p className=\"text-sm font-bold underline underline-offset-2\">\n Read {isExpanded ? 'less' : 'more'}\n </p>\n </Button>\n </div>\n )\n}\n","import { Slot } from '@radix-ui/react-slot'\nimport { cva, type VariantProps } from 'cva'\nimport React, { forwardRef } from 'react'\n\nimport { cn } from '@/lib/utils'\n\n/**\n * Props for the Button component.\n * @interface ButtonProps\n * @extends {React.ButtonHTMLAttributes<HTMLButtonElement>}\n * @extends {VariantProps<typeof buttonVariants>}\n */\ninterface ButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement>,\n VariantProps<typeof buttonVariants> {\n /**\n * When true, the component will render its children directly without wrapping them in a button element.\n * Useful when you want to use the button styles on a different element.\n * @default false\n */\n asChild?: boolean\n}\n\n/**\n * A versatile button component that supports multiple variants and sizes.\n *\n * @component\n * @example\n * ```tsx\n * // Default button\n * <Button>Click me</Button>\n *\n * // Primary variant with large size\n * <Button variant=\"primary\" size=\"lg\">Large Button</Button>\n *\n * // As a link\n * <Button asChild>\n * <a href=\"/somewhere\">Go somewhere</a>\n * </Button>\n * ```\n */\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant, size, asChild = false, type = 'button', ...props }, ref) => {\n const Component = asChild ? Slot : 'button'\n\n return (\n <Component\n className={cn(buttonVariants({ variant, size, className }))}\n type={type}\n ref={ref}\n {...props}\n />\n )\n }\n)\nButton.displayName = 'Button'\n\n/**\n * Variant definitions for the Button component using class-variance-authority.\n * Provides consistent styling across different button variations.\n */\nexport const buttonVariants = cva(\n [\n 'flex',\n 'items-center',\n 'justify-center',\n 'gap-2',\n 'rounded-full',\n 'font-bold',\n 'outline-2',\n 'outline-offset-2',\n 'outline-dashed',\n 'outline-transparent',\n ],\n {\n variants: {\n variant: {\n neutral: [\n 'bg-black',\n 'text-white',\n 'hover:bg-grey-90',\n 'active:bg-grey-80',\n 'focus:outline-purple-100',\n 'disabled:text-grey-40',\n 'disabled:bg-grey-10',\n ],\n primary: [\n 'bg-pickle-100',\n 'text-black',\n 'hover:bg-pickle-80',\n 'active:bg-pickle-60',\n 'focus:outline-purple-100',\n 'disabled:text-grey-40',\n 'disabled:bg-grey-10',\n ],\n secondary: [\n 'bg-green-80',\n 'text-white',\n 'hover:bg-green-90',\n 'active:bg-green-100',\n 'focus:outline-pickle-100',\n 'disabled:text-grey-40',\n 'disabled:bg-grey-10',\n ],\n transparent: [\n 'text-white',\n 'hover:bg-green-80',\n 'active:bg-green-100',\n 'focus:outline-pickle-100',\n 'disabled:text-grey-40',\n ],\n link: [\n 'leading-tight',\n 'text-black',\n 'underline',\n 'hover:text-purple-100',\n 'focus:text-black',\n 'focus:outline-purple-100',\n 'active:text-purple-80',\n ],\n },\n size: {\n small: ['h-10', 'text-sm', 'px-4', 'py-2'],\n medium: ['h-12', 'text-base', 'px-6', 'py-3'],\n large: ['h-14', 'text-lg', 'px-8', 'py-4'],\n },\n },\n defaultVariants: {\n variant: 'neutral',\n size: 'medium',\n },\n compoundVariants: [\n {\n variant: 'link',\n size: 'small',\n class: ['h-3', 'text-xs', 'p-0'],\n },\n {\n variant: 'link',\n size: 'medium',\n class: ['h-4', 'text-sm', 'p-0'],\n },\n {\n variant: 'link',\n size: 'large',\n class: ['h-6', 'text-base', 'p-0'],\n },\n ],\n }\n)\n","import { type ClassValue, clsx } from 'clsx'\nimport { twMerge } from 'tailwind-merge'\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACEA,IAAAA,gBAAyD;AACzD,4BAAqB;;;ACHrB,wBAAqB;AACrB,iBAAuC;AACvC,mBAAkC;;;ACFlC,kBAAsC;AACtC,4BAAwB;AAEjB,SAAS,MAAM,QAAsB;AAC1C,aAAO,mCAAQ,kBAAK,MAAM,CAAC;AAC7B;;;ADyCM;AALC,IAAM,aAAS;AAAA,EACpB,CAAC,EAAE,WAAW,SAAS,MAAM,UAAU,OAAO,OAAO,UAAU,GAAG,MAAM,GAAG,QAAQ;AACjF,UAAM,YAAY,UAAU,yBAAO;AAEnC,WACE;AAAA,MAAC;AAAA;AAAA,QACC,WAAW,GAAG,eAAe,EAAE,SAAS,MAAM,UAAU,CAAC,CAAC;AAAA,QAC1D;AAAA,QACA;AAAA,QACC,GAAG;AAAA;AAAA,IACN;AAAA,EAEJ;AACF;AACA,OAAO,cAAc;AAMd,IAAM,qBAAiB;AAAA,EAC5B;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,SAAS;AAAA,QACP,SAAS;AAAA,UACP;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,QACA,SAAS;AAAA,UACP;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,QACA,WAAW;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,QACA,aAAa;AAAA,UACX;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,QACA,MAAM;AAAA,UACJ;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,MACA,MAAM;AAAA,QACJ,OAAO,CAAC,QAAQ,WAAW,QAAQ,MAAM;AAAA,QACzC,QAAQ,CAAC,QAAQ,aAAa,QAAQ,MAAM;AAAA,QAC5C,OAAO,CAAC,QAAQ,WAAW,QAAQ,MAAM;AAAA,MAC3C;AAAA,IACF;AAAA,IACA,iBAAiB;AAAA,MACf,SAAS;AAAA,MACT,MAAM;AAAA,IACR;AAAA,IACA,kBAAkB;AAAA,MAChB;AAAA,QACE,SAAS;AAAA,QACT,MAAM;AAAA,QACN,OAAO,CAAC,OAAO,WAAW,KAAK;AAAA,MACjC;AAAA,MACA;AAAA,QACE,SAAS;AAAA,QACT,MAAM;AAAA,QACN,OAAO,CAAC,OAAO,WAAW,KAAK;AAAA,MACjC;AAAA,MACA;AAAA,QACE,SAAS;AAAA,QACT,MAAM;AAAA,QACN,OAAO,CAAC,OAAO,aAAa,KAAK;AAAA,MACnC;AAAA,IACF;AAAA,EACF;AACF;;;ADvGQ,IAAAC,sBAAA;AAnCD,SAAS,SAAS,EAAE,MAAM,GAAG,MAAM,GAA4B;AACpE,QAAM,CAAC,YAAY,aAAa,QAAI,wBAAS,KAAK;AAClD,QAAM,CAAC,UAAU,WAAW,QAAI,wBAAS,GAAG;AAE5C,+BAAU,MAAM;AACd,UAAM,iBAAiB,MAAM;AAC3B,YAAM,cAAc,OAAO;AAC3B,UAAI,eAAe,KAAK;AACtB,oBAAY,EAAE;AAAA,MAChB,OAAO;AACL,oBAAY,GAAG;AAAA,MACjB;AAAA,IACF;AAEA,mBAAe;AACf,WAAO,iBAAiB,UAAU,cAAc;AAEhD,WAAO,MAAM,OAAO,oBAAoB,UAAU,cAAc;AAAA,EAClE,GAAG,CAAC,CAAC;AAEL,WAAS,mBAAmBC,OAAcC,WAAkBC,aAA6B;AACvF,UAAM,QAAQF,MAAK,MAAM,GAAG;AAE5B,UAAMG,WAAUD,cAAaF,QAAO,MAAM,MAAM,GAAGC,SAAQ,EAAE,KAAK,GAAG;AACrE,UAAM,eAAeC,cAAa,KAAK;AACvC,WAAO,GAAGC,QAAO,IAAI,YAAY;AAAA,EACnC;AAEA,QAAM,aAAa,MAAM,cAAc,CAAC,UAAU;AAElD,QAAM,UAAU,mBAAmB,MAAM,UAAU,UAAU;AAE7D,SACE,8CAAC,SAAK,GAAG,OACP;AAAA,iDAAC,SAAI,eAAY,kBAAiB,WAAU,qBAC1C,uDAAC,sBAAAC,SAAA,EAAU,mBAAQ,GACrB;AAAA,IACA;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,WAAU;AAAA,QACV,SAAQ;AAAA,QACR,SAAS;AAAA,QAET,wDAAC,OAAE,WAAU,kDAAiD;AAAA;AAAA,UACtD,aAAa,SAAS;AAAA,WAC9B;AAAA;AAAA,IACF;AAAA,KACF;AAEJ;;;ADlDI,IAAAC,sBAAA;AAJG,SAAS,eAAe,EAAE,YAAY,GAAwB;AACnE,MAAI,CAAC,YAAa,QAAO;AAEzB,SACE,8CAAC,SAAI,WAAU,8BACb;AAAA,iDAAC,QAAG,WAAU,qBAAoB,6BAAe;AAAA,IACjD,6CAAC,YAAS,MAAM,aAAa;AAAA,KAC/B;AAEJ;","names":["import_react","import_jsx_runtime","text","maxWords","isExpanded","snippet","Markdown","import_jsx_runtime"]}
1
+ {"version":3,"sources":["../../../src/components/jobPost/JobDescription.tsx","../../../src/components/ui/ReadMore.tsx","../../../src/components/ui/Button.tsx","../../../src/lib/utils.ts"],"sourcesContent":["import { ReadMore } from '@/components/ui/ReadMore'\n\nexport type JobDescriptionProps = {\n description?: string\n}\n\nexport function JobDescription({ description }: JobDescriptionProps) {\n if (!description) return null\n\n return (\n <div className=\"flex w-full flex-col gap-2\">\n <h3 className=\"text-xl font-bold\">Job Description</h3>\n <ReadMore text={description} />\n </div>\n )\n}\n","'use client'\n\nimport { type ComponentProps, useEffect, useState } from 'react'\nimport Markdown from 'react-markdown'\n\nimport { Button } from '@/components/ui/Button'\n\nexport type ReadMoreProps = ComponentProps<'div'> & {\n text: string\n}\n\nexport function ReadMore({ text, ...props }: Readonly<ReadMoreProps>) {\n const [isExpanded, setIsExpanded] = useState(false)\n const [maxWords, setMaxWords] = useState(160)\n\n const isOverMaxWords = text.split(' ').length > maxWords\n\n useEffect(() => {\n const updateMaxWords = () => {\n const windowWidth = window.innerWidth\n if (windowWidth <= 768) {\n setMaxWords(50)\n } else {\n setMaxWords(160)\n }\n }\n\n updateMaxWords()\n window.addEventListener('resize', updateMaxWords)\n\n return () => window.removeEventListener('resize', updateMaxWords)\n }, [])\n\n function createReadMoreText(text: string, maxWords: number, isExpanded: boolean): string {\n if (!isOverMaxWords) return text\n\n const words = text.split(' ')\n const snippet = isExpanded ? text : words.slice(0, maxWords).join(' ')\n const readMoreText = isExpanded ? '' : '...'\n return `${snippet} ${readMoreText}`\n }\n\n const toggleText = () => setIsExpanded(!isExpanded)\n\n const snippet = createReadMoreText(text, maxWords, isExpanded)\n\n return (\n <div {...props}>\n <div data-testid=\"read-more-text\" className=\"prose lg:prose-lg\">\n <Markdown>{snippet}</Markdown>\n </div>\n {isOverMaxWords && (\n <Button\n type=\"button\"\n className=\"mt-2 flex items-center justify-center\"\n variant=\"link\"\n onClick={toggleText}\n >\n <p className=\"text-sm font-bold underline underline-offset-2\">\n Read {isExpanded ? 'less' : 'more'}\n </p>\n </Button>\n )}\n </div>\n )\n}\n","import { Slot } from '@radix-ui/react-slot'\nimport { cva, type VariantProps } from 'cva'\nimport React, { forwardRef } from 'react'\n\nimport { cn } from '@/lib/utils'\n\n/**\n * Props for the Button component.\n * @interface ButtonProps\n * @extends {React.ButtonHTMLAttributes<HTMLButtonElement>}\n * @extends {VariantProps<typeof buttonVariants>}\n */\ninterface ButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement>,\n VariantProps<typeof buttonVariants> {\n /**\n * When true, the component will render its children directly without wrapping them in a button element.\n * Useful when you want to use the button styles on a different element.\n * @default false\n */\n asChild?: boolean\n}\n\n/**\n * A versatile button component that supports multiple variants and sizes.\n *\n * @component\n * @example\n * ```tsx\n * // Default button\n * <Button>Click me</Button>\n *\n * // Primary variant with large size\n * <Button variant=\"primary\" size=\"lg\">Large Button</Button>\n *\n * // As a link\n * <Button asChild>\n * <a href=\"/somewhere\">Go somewhere</a>\n * </Button>\n * ```\n */\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant, size, asChild = false, type = 'button', ...props }, ref) => {\n const Component = asChild ? Slot : 'button'\n\n return (\n <Component\n className={cn(buttonVariants({ variant, size, className }))}\n type={type}\n ref={ref}\n {...props}\n />\n )\n }\n)\nButton.displayName = 'Button'\n\n/**\n * Variant definitions for the Button component using class-variance-authority.\n * Provides consistent styling across different button variations.\n */\nexport const buttonVariants = cva(\n [\n 'flex',\n 'items-center',\n 'justify-center',\n 'gap-2',\n 'rounded-full',\n 'font-bold',\n 'outline-2',\n 'outline-offset-2',\n 'outline-dashed',\n 'outline-transparent',\n ],\n {\n variants: {\n variant: {\n neutral: [\n 'bg-black',\n 'text-white',\n 'hover:bg-grey-90',\n 'active:bg-grey-80',\n 'focus:outline-purple-100',\n 'disabled:text-grey-40',\n 'disabled:bg-grey-10',\n ],\n primary: [\n 'bg-pickle-100',\n 'text-black',\n 'hover:bg-pickle-80',\n 'active:bg-pickle-60',\n 'focus:outline-purple-100',\n 'disabled:text-grey-40',\n 'disabled:bg-grey-10',\n ],\n secondary: [\n 'bg-green-80',\n 'text-white',\n 'hover:bg-green-90',\n 'active:bg-green-100',\n 'focus:outline-pickle-100',\n 'disabled:text-grey-40',\n 'disabled:bg-grey-10',\n ],\n transparent: [\n 'text-white',\n 'hover:bg-green-80',\n 'active:bg-green-100',\n 'focus:outline-pickle-100',\n 'disabled:text-grey-40',\n ],\n link: [\n 'leading-tight',\n 'text-black',\n 'underline',\n 'hover:text-purple-100',\n 'focus:text-black',\n 'focus:outline-purple-100',\n 'active:text-purple-80',\n ],\n },\n size: {\n small: ['h-10', 'text-sm', 'px-4', 'py-2'],\n medium: ['h-12', 'text-base', 'px-6', 'py-3'],\n large: ['h-14', 'text-lg', 'px-8', 'py-4'],\n },\n },\n defaultVariants: {\n variant: 'neutral',\n size: 'medium',\n },\n compoundVariants: [\n {\n variant: 'link',\n size: 'small',\n class: ['h-3', 'text-xs', 'p-0'],\n },\n {\n variant: 'link',\n size: 'medium',\n class: ['h-4', 'text-sm', 'p-0'],\n },\n {\n variant: 'link',\n size: 'large',\n class: ['h-6', 'text-base', 'p-0'],\n },\n ],\n }\n)\n","import { type ClassValue, clsx } from 'clsx'\nimport { twMerge } from 'tailwind-merge'\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n"],"mappings":"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","names":["import_react","import_jsx_runtime","text","maxWords","isExpanded","snippet","Markdown","import_jsx_runtime"]}
@@ -126,6 +126,7 @@ import { jsx as jsx2, jsxs } from "react/jsx-runtime";
126
126
  function ReadMore({ text, ...props }) {
127
127
  const [isExpanded, setIsExpanded] = useState(false);
128
128
  const [maxWords, setMaxWords] = useState(160);
129
+ const isOverMaxWords = text.split(" ").length > maxWords;
129
130
  useEffect(() => {
130
131
  const updateMaxWords = () => {
131
132
  const windowWidth = window.innerWidth;
@@ -140,6 +141,7 @@ function ReadMore({ text, ...props }) {
140
141
  return () => window.removeEventListener("resize", updateMaxWords);
141
142
  }, []);
142
143
  function createReadMoreText(text2, maxWords2, isExpanded2) {
144
+ if (!isOverMaxWords) return text2;
143
145
  const words = text2.split(" ");
144
146
  const snippet2 = isExpanded2 ? text2 : words.slice(0, maxWords2).join(" ");
145
147
  const readMoreText = isExpanded2 ? "" : "...";
@@ -149,7 +151,7 @@ function ReadMore({ text, ...props }) {
149
151
  const snippet = createReadMoreText(text, maxWords, isExpanded);
150
152
  return /* @__PURE__ */ jsxs("div", { ...props, children: [
151
153
  /* @__PURE__ */ jsx2("div", { "data-testid": "read-more-text", className: "prose lg:prose-lg", children: /* @__PURE__ */ jsx2(Markdown, { children: snippet }) }),
152
- /* @__PURE__ */ jsx2(
154
+ isOverMaxWords && /* @__PURE__ */ jsx2(
153
155
  Button,
154
156
  {
155
157
  type: "button",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/ui/ReadMore.tsx","../../../src/components/ui/Button.tsx","../../../src/lib/utils.ts","../../../src/components/jobPost/JobDescription.tsx"],"sourcesContent":["'use client'\n\nimport { type ComponentProps, useEffect, useState } from 'react'\nimport Markdown from 'react-markdown'\n\nimport { Button } from '@/components/ui/Button'\n\nexport type ReadMoreProps = ComponentProps<'div'> & {\n text: string\n}\n\nexport function ReadMore({ text, ...props }: Readonly<ReadMoreProps>) {\n const [isExpanded, setIsExpanded] = useState(false)\n const [maxWords, setMaxWords] = useState(160)\n\n useEffect(() => {\n const updateMaxWords = () => {\n const windowWidth = window.innerWidth\n if (windowWidth <= 768) {\n setMaxWords(50)\n } else {\n setMaxWords(160)\n }\n }\n\n updateMaxWords()\n window.addEventListener('resize', updateMaxWords)\n\n return () => window.removeEventListener('resize', updateMaxWords)\n }, [])\n\n function createReadMoreText(text: string, maxWords: number, isExpanded: boolean): string {\n const words = text.split(' ')\n\n const snippet = isExpanded ? text : words.slice(0, maxWords).join(' ')\n const readMoreText = isExpanded ? '' : '...'\n return `${snippet} ${readMoreText}`\n }\n\n const toggleText = () => setIsExpanded(!isExpanded)\n\n const snippet = createReadMoreText(text, maxWords, isExpanded)\n\n return (\n <div {...props}>\n <div data-testid=\"read-more-text\" className=\"prose lg:prose-lg\">\n <Markdown>{snippet}</Markdown>\n </div>\n <Button\n type=\"button\"\n className=\"mt-2 flex items-center justify-center\"\n variant=\"link\"\n onClick={toggleText}\n >\n <p className=\"text-sm font-bold underline underline-offset-2\">\n Read {isExpanded ? 'less' : 'more'}\n </p>\n </Button>\n </div>\n )\n}\n","import { Slot } from '@radix-ui/react-slot'\nimport { cva, type VariantProps } from 'cva'\nimport React, { forwardRef } from 'react'\n\nimport { cn } from '@/lib/utils'\n\n/**\n * Props for the Button component.\n * @interface ButtonProps\n * @extends {React.ButtonHTMLAttributes<HTMLButtonElement>}\n * @extends {VariantProps<typeof buttonVariants>}\n */\ninterface ButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement>,\n VariantProps<typeof buttonVariants> {\n /**\n * When true, the component will render its children directly without wrapping them in a button element.\n * Useful when you want to use the button styles on a different element.\n * @default false\n */\n asChild?: boolean\n}\n\n/**\n * A versatile button component that supports multiple variants and sizes.\n *\n * @component\n * @example\n * ```tsx\n * // Default button\n * <Button>Click me</Button>\n *\n * // Primary variant with large size\n * <Button variant=\"primary\" size=\"lg\">Large Button</Button>\n *\n * // As a link\n * <Button asChild>\n * <a href=\"/somewhere\">Go somewhere</a>\n * </Button>\n * ```\n */\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant, size, asChild = false, type = 'button', ...props }, ref) => {\n const Component = asChild ? Slot : 'button'\n\n return (\n <Component\n className={cn(buttonVariants({ variant, size, className }))}\n type={type}\n ref={ref}\n {...props}\n />\n )\n }\n)\nButton.displayName = 'Button'\n\n/**\n * Variant definitions for the Button component using class-variance-authority.\n * Provides consistent styling across different button variations.\n */\nexport const buttonVariants = cva(\n [\n 'flex',\n 'items-center',\n 'justify-center',\n 'gap-2',\n 'rounded-full',\n 'font-bold',\n 'outline-2',\n 'outline-offset-2',\n 'outline-dashed',\n 'outline-transparent',\n ],\n {\n variants: {\n variant: {\n neutral: [\n 'bg-black',\n 'text-white',\n 'hover:bg-grey-90',\n 'active:bg-grey-80',\n 'focus:outline-purple-100',\n 'disabled:text-grey-40',\n 'disabled:bg-grey-10',\n ],\n primary: [\n 'bg-pickle-100',\n 'text-black',\n 'hover:bg-pickle-80',\n 'active:bg-pickle-60',\n 'focus:outline-purple-100',\n 'disabled:text-grey-40',\n 'disabled:bg-grey-10',\n ],\n secondary: [\n 'bg-green-80',\n 'text-white',\n 'hover:bg-green-90',\n 'active:bg-green-100',\n 'focus:outline-pickle-100',\n 'disabled:text-grey-40',\n 'disabled:bg-grey-10',\n ],\n transparent: [\n 'text-white',\n 'hover:bg-green-80',\n 'active:bg-green-100',\n 'focus:outline-pickle-100',\n 'disabled:text-grey-40',\n ],\n link: [\n 'leading-tight',\n 'text-black',\n 'underline',\n 'hover:text-purple-100',\n 'focus:text-black',\n 'focus:outline-purple-100',\n 'active:text-purple-80',\n ],\n },\n size: {\n small: ['h-10', 'text-sm', 'px-4', 'py-2'],\n medium: ['h-12', 'text-base', 'px-6', 'py-3'],\n large: ['h-14', 'text-lg', 'px-8', 'py-4'],\n },\n },\n defaultVariants: {\n variant: 'neutral',\n size: 'medium',\n },\n compoundVariants: [\n {\n variant: 'link',\n size: 'small',\n class: ['h-3', 'text-xs', 'p-0'],\n },\n {\n variant: 'link',\n size: 'medium',\n class: ['h-4', 'text-sm', 'p-0'],\n },\n {\n variant: 'link',\n size: 'large',\n class: ['h-6', 'text-base', 'p-0'],\n },\n ],\n }\n)\n","import { type ClassValue, clsx } from 'clsx'\nimport { twMerge } from 'tailwind-merge'\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n","import { ReadMore } from '@/components/ui/ReadMore'\n\nexport type JobDescriptionProps = {\n description?: string\n}\n\nexport function JobDescription({ description }: JobDescriptionProps) {\n if (!description) return null\n\n return (\n <div className=\"flex w-full flex-col gap-2\">\n <h3 className=\"text-xl font-bold\">Job Description</h3>\n <ReadMore text={description} />\n </div>\n )\n}\n"],"mappings":";AAEA,SAA8B,WAAW,gBAAgB;AACzD,OAAO,cAAc;;;ACHrB,SAAS,YAAY;AACrB,SAAS,WAA8B;AACvC,SAAgB,kBAAkB;;;ACFlC,SAA0B,YAAY;AACtC,SAAS,eAAe;AAEjB,SAAS,MAAM,QAAsB;AAC1C,SAAO,QAAQ,KAAK,MAAM,CAAC;AAC7B;;;ADyCM;AALC,IAAM,SAAS;AAAA,EACpB,CAAC,EAAE,WAAW,SAAS,MAAM,UAAU,OAAO,OAAO,UAAU,GAAG,MAAM,GAAG,QAAQ;AACjF,UAAM,YAAY,UAAU,OAAO;AAEnC,WACE;AAAA,MAAC;AAAA;AAAA,QACC,WAAW,GAAG,eAAe,EAAE,SAAS,MAAM,UAAU,CAAC,CAAC;AAAA,QAC1D;AAAA,QACA;AAAA,QACC,GAAG;AAAA;AAAA,IACN;AAAA,EAEJ;AACF;AACA,OAAO,cAAc;AAMd,IAAM,iBAAiB;AAAA,EAC5B;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,SAAS;AAAA,QACP,SAAS;AAAA,UACP;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,QACA,SAAS;AAAA,UACP;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,QACA,WAAW;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,QACA,aAAa;AAAA,UACX;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,QACA,MAAM;AAAA,UACJ;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,MACA,MAAM;AAAA,QACJ,OAAO,CAAC,QAAQ,WAAW,QAAQ,MAAM;AAAA,QACzC,QAAQ,CAAC,QAAQ,aAAa,QAAQ,MAAM;AAAA,QAC5C,OAAO,CAAC,QAAQ,WAAW,QAAQ,MAAM;AAAA,MAC3C;AAAA,IACF;AAAA,IACA,iBAAiB;AAAA,MACf,SAAS;AAAA,MACT,MAAM;AAAA,IACR;AAAA,IACA,kBAAkB;AAAA,MAChB;AAAA,QACE,SAAS;AAAA,QACT,MAAM;AAAA,QACN,OAAO,CAAC,OAAO,WAAW,KAAK;AAAA,MACjC;AAAA,MACA;AAAA,QACE,SAAS;AAAA,QACT,MAAM;AAAA,QACN,OAAO,CAAC,OAAO,WAAW,KAAK;AAAA,MACjC;AAAA,MACA;AAAA,QACE,SAAS;AAAA,QACT,MAAM;AAAA,QACN,OAAO,CAAC,OAAO,aAAa,KAAK;AAAA,MACnC;AAAA,IACF;AAAA,EACF;AACF;;;ADvGQ,gBAAAA,MAQA,YARA;AAnCD,SAAS,SAAS,EAAE,MAAM,GAAG,MAAM,GAA4B;AACpE,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,KAAK;AAClD,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,GAAG;AAE5C,YAAU,MAAM;AACd,UAAM,iBAAiB,MAAM;AAC3B,YAAM,cAAc,OAAO;AAC3B,UAAI,eAAe,KAAK;AACtB,oBAAY,EAAE;AAAA,MAChB,OAAO;AACL,oBAAY,GAAG;AAAA,MACjB;AAAA,IACF;AAEA,mBAAe;AACf,WAAO,iBAAiB,UAAU,cAAc;AAEhD,WAAO,MAAM,OAAO,oBAAoB,UAAU,cAAc;AAAA,EAClE,GAAG,CAAC,CAAC;AAEL,WAAS,mBAAmBC,OAAcC,WAAkBC,aAA6B;AACvF,UAAM,QAAQF,MAAK,MAAM,GAAG;AAE5B,UAAMG,WAAUD,cAAaF,QAAO,MAAM,MAAM,GAAGC,SAAQ,EAAE,KAAK,GAAG;AACrE,UAAM,eAAeC,cAAa,KAAK;AACvC,WAAO,GAAGC,QAAO,IAAI,YAAY;AAAA,EACnC;AAEA,QAAM,aAAa,MAAM,cAAc,CAAC,UAAU;AAElD,QAAM,UAAU,mBAAmB,MAAM,UAAU,UAAU;AAE7D,SACE,qBAAC,SAAK,GAAG,OACP;AAAA,oBAAAJ,KAAC,SAAI,eAAY,kBAAiB,WAAU,qBAC1C,0BAAAA,KAAC,YAAU,mBAAQ,GACrB;AAAA,IACA,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,WAAU;AAAA,QACV,SAAQ;AAAA,QACR,SAAS;AAAA,QAET,+BAAC,OAAE,WAAU,kDAAiD;AAAA;AAAA,UACtD,aAAa,SAAS;AAAA,WAC9B;AAAA;AAAA,IACF;AAAA,KACF;AAEJ;;;AGlDI,SACE,OAAAK,MADF,QAAAC,aAAA;AAJG,SAAS,eAAe,EAAE,YAAY,GAAwB;AACnE,MAAI,CAAC,YAAa,QAAO;AAEzB,SACE,gBAAAA,MAAC,SAAI,WAAU,8BACb;AAAA,oBAAAD,KAAC,QAAG,WAAU,qBAAoB,6BAAe;AAAA,IACjD,gBAAAA,KAAC,YAAS,MAAM,aAAa;AAAA,KAC/B;AAEJ;","names":["jsx","text","maxWords","isExpanded","snippet","jsx","jsxs"]}
1
+ {"version":3,"sources":["../../../src/components/ui/ReadMore.tsx","../../../src/components/ui/Button.tsx","../../../src/lib/utils.ts","../../../src/components/jobPost/JobDescription.tsx"],"sourcesContent":["'use client'\n\nimport { type ComponentProps, useEffect, useState } from 'react'\nimport Markdown from 'react-markdown'\n\nimport { Button } from '@/components/ui/Button'\n\nexport type ReadMoreProps = ComponentProps<'div'> & {\n text: string\n}\n\nexport function ReadMore({ text, ...props }: Readonly<ReadMoreProps>) {\n const [isExpanded, setIsExpanded] = useState(false)\n const [maxWords, setMaxWords] = useState(160)\n\n const isOverMaxWords = text.split(' ').length > maxWords\n\n useEffect(() => {\n const updateMaxWords = () => {\n const windowWidth = window.innerWidth\n if (windowWidth <= 768) {\n setMaxWords(50)\n } else {\n setMaxWords(160)\n }\n }\n\n updateMaxWords()\n window.addEventListener('resize', updateMaxWords)\n\n return () => window.removeEventListener('resize', updateMaxWords)\n }, [])\n\n function createReadMoreText(text: string, maxWords: number, isExpanded: boolean): string {\n if (!isOverMaxWords) return text\n\n const words = text.split(' ')\n const snippet = isExpanded ? text : words.slice(0, maxWords).join(' ')\n const readMoreText = isExpanded ? '' : '...'\n return `${snippet} ${readMoreText}`\n }\n\n const toggleText = () => setIsExpanded(!isExpanded)\n\n const snippet = createReadMoreText(text, maxWords, isExpanded)\n\n return (\n <div {...props}>\n <div data-testid=\"read-more-text\" className=\"prose lg:prose-lg\">\n <Markdown>{snippet}</Markdown>\n </div>\n {isOverMaxWords && (\n <Button\n type=\"button\"\n className=\"mt-2 flex items-center justify-center\"\n variant=\"link\"\n onClick={toggleText}\n >\n <p className=\"text-sm font-bold underline underline-offset-2\">\n Read {isExpanded ? 'less' : 'more'}\n </p>\n </Button>\n )}\n </div>\n )\n}\n","import { Slot } from '@radix-ui/react-slot'\nimport { cva, type VariantProps } from 'cva'\nimport React, { forwardRef } from 'react'\n\nimport { cn } from '@/lib/utils'\n\n/**\n * Props for the Button component.\n * @interface ButtonProps\n * @extends {React.ButtonHTMLAttributes<HTMLButtonElement>}\n * @extends {VariantProps<typeof buttonVariants>}\n */\ninterface ButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement>,\n VariantProps<typeof buttonVariants> {\n /**\n * When true, the component will render its children directly without wrapping them in a button element.\n * Useful when you want to use the button styles on a different element.\n * @default false\n */\n asChild?: boolean\n}\n\n/**\n * A versatile button component that supports multiple variants and sizes.\n *\n * @component\n * @example\n * ```tsx\n * // Default button\n * <Button>Click me</Button>\n *\n * // Primary variant with large size\n * <Button variant=\"primary\" size=\"lg\">Large Button</Button>\n *\n * // As a link\n * <Button asChild>\n * <a href=\"/somewhere\">Go somewhere</a>\n * </Button>\n * ```\n */\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant, size, asChild = false, type = 'button', ...props }, ref) => {\n const Component = asChild ? Slot : 'button'\n\n return (\n <Component\n className={cn(buttonVariants({ variant, size, className }))}\n type={type}\n ref={ref}\n {...props}\n />\n )\n }\n)\nButton.displayName = 'Button'\n\n/**\n * Variant definitions for the Button component using class-variance-authority.\n * Provides consistent styling across different button variations.\n */\nexport const buttonVariants = cva(\n [\n 'flex',\n 'items-center',\n 'justify-center',\n 'gap-2',\n 'rounded-full',\n 'font-bold',\n 'outline-2',\n 'outline-offset-2',\n 'outline-dashed',\n 'outline-transparent',\n ],\n {\n variants: {\n variant: {\n neutral: [\n 'bg-black',\n 'text-white',\n 'hover:bg-grey-90',\n 'active:bg-grey-80',\n 'focus:outline-purple-100',\n 'disabled:text-grey-40',\n 'disabled:bg-grey-10',\n ],\n primary: [\n 'bg-pickle-100',\n 'text-black',\n 'hover:bg-pickle-80',\n 'active:bg-pickle-60',\n 'focus:outline-purple-100',\n 'disabled:text-grey-40',\n 'disabled:bg-grey-10',\n ],\n secondary: [\n 'bg-green-80',\n 'text-white',\n 'hover:bg-green-90',\n 'active:bg-green-100',\n 'focus:outline-pickle-100',\n 'disabled:text-grey-40',\n 'disabled:bg-grey-10',\n ],\n transparent: [\n 'text-white',\n 'hover:bg-green-80',\n 'active:bg-green-100',\n 'focus:outline-pickle-100',\n 'disabled:text-grey-40',\n ],\n link: [\n 'leading-tight',\n 'text-black',\n 'underline',\n 'hover:text-purple-100',\n 'focus:text-black',\n 'focus:outline-purple-100',\n 'active:text-purple-80',\n ],\n },\n size: {\n small: ['h-10', 'text-sm', 'px-4', 'py-2'],\n medium: ['h-12', 'text-base', 'px-6', 'py-3'],\n large: ['h-14', 'text-lg', 'px-8', 'py-4'],\n },\n },\n defaultVariants: {\n variant: 'neutral',\n size: 'medium',\n },\n compoundVariants: [\n {\n variant: 'link',\n size: 'small',\n class: ['h-3', 'text-xs', 'p-0'],\n },\n {\n variant: 'link',\n size: 'medium',\n class: ['h-4', 'text-sm', 'p-0'],\n },\n {\n variant: 'link',\n size: 'large',\n class: ['h-6', 'text-base', 'p-0'],\n },\n ],\n }\n)\n","import { type ClassValue, clsx } from 'clsx'\nimport { twMerge } from 'tailwind-merge'\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n","import { ReadMore } from '@/components/ui/ReadMore'\n\nexport type JobDescriptionProps = {\n description?: string\n}\n\nexport function JobDescription({ description }: JobDescriptionProps) {\n if (!description) return null\n\n return (\n <div className=\"flex w-full flex-col gap-2\">\n <h3 className=\"text-xl font-bold\">Job Description</h3>\n <ReadMore text={description} />\n </div>\n )\n}\n"],"mappings":"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","names":["jsx","text","maxWords","isExpanded","snippet","jsx","jsxs"]}
@@ -338,6 +338,7 @@ var import_jsx_runtime8 = require("react/jsx-runtime");
338
338
  function ReadMore({ text, ...props }) {
339
339
  const [isExpanded, setIsExpanded] = (0, import_react2.useState)(false);
340
340
  const [maxWords, setMaxWords] = (0, import_react2.useState)(160);
341
+ const isOverMaxWords = text.split(" ").length > maxWords;
341
342
  (0, import_react2.useEffect)(() => {
342
343
  const updateMaxWords = () => {
343
344
  const windowWidth = window.innerWidth;
@@ -352,6 +353,7 @@ function ReadMore({ text, ...props }) {
352
353
  return () => window.removeEventListener("resize", updateMaxWords);
353
354
  }, []);
354
355
  function createReadMoreText(text2, maxWords2, isExpanded2) {
356
+ if (!isOverMaxWords) return text2;
355
357
  const words = text2.split(" ");
356
358
  const snippet2 = isExpanded2 ? text2 : words.slice(0, maxWords2).join(" ");
357
359
  const readMoreText = isExpanded2 ? "" : "...";
@@ -361,7 +363,7 @@ function ReadMore({ text, ...props }) {
361
363
  const snippet = createReadMoreText(text, maxWords, isExpanded);
362
364
  return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { ...props, children: [
363
365
  /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { "data-testid": "read-more-text", className: "prose lg:prose-lg", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_markdown.default, { children: snippet }) }),
364
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
366
+ isOverMaxWords && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
365
367
  Button,
366
368
  {
367
369
  type: "button",
@@ -1593,7 +1595,7 @@ var jobPostSchema2 = jobPostSchema.extend({
1593
1595
 
1594
1596
  // src/lib/salaryRange.ts
1595
1597
  var CurrencyEnum2 = shared_pickle_output_latest_exports.CurrencyEnum;
1596
- function salaryRange(salary) {
1598
+ function salaryRange(salary, showUnitText = true) {
1597
1599
  if (!salary) return null;
1598
1600
  let min = salary.minValue;
1599
1601
  let max = salary.maxValue;
@@ -1612,17 +1614,19 @@ function salaryRange(salary) {
1612
1614
  single = value.value;
1613
1615
  unitText = value.unitText;
1614
1616
  }
1615
- if (unitText === "YEAR") unitText = "per year";
1616
- if (unitText === "MONTH") unitText = "per month";
1617
- if (unitText === "WEEK") unitText = "per week";
1618
- if (unitText === "DAY") unitText = "per day";
1619
- if (unitText === "PER_ACTIVITY") unitText = "per activity";
1620
- if (unitText === "HOUR") unitText = "per hour";
1621
- if (min == null && max == null && single == null) return null;
1622
- if (single != null) return sign + single.toLocaleString() + " " + unitText;
1623
- if (min === max) return sign + min?.toLocaleString() + " " + unitText;
1624
- if (min != null && max != null)
1625
- return sign + min?.toLocaleString() + " - " + sign + max?.toLocaleString() + " " + unitText;
1617
+ if (unitText === "YEAR") unitText = " per year";
1618
+ if (unitText === "MONTH") unitText = " per month";
1619
+ if (unitText === "WEEK") unitText = " per week";
1620
+ if (unitText === "DAY") unitText = " per day";
1621
+ if (unitText === "PER_ACTIVITY") unitText = " per activity";
1622
+ if (unitText === "HOUR") unitText = " per hour";
1623
+ if (showUnitText === false) unitText = "";
1624
+ const isValid = (v) => v != null && v >= 0;
1625
+ if (!isValid(min) && !isValid(max) && !isValid(single)) return null;
1626
+ if (isValid(single)) return sign + single.toLocaleString() + unitText;
1627
+ if (min === max) return sign + min?.toLocaleString() + unitText;
1628
+ if (isValid(min) && isValid(max))
1629
+ return sign + min?.toLocaleString() + " - " + sign + max?.toLocaleString() + unitText;
1626
1630
  return null;
1627
1631
  }
1628
1632