@myst-theme/frontmatter 0.14.0 → 0.14.2

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.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @myst-theme/frontmatter
2
2
 
3
3
  [![@myst-theme/frontmatter on npm](https://img.shields.io/npm/v/@myst-theme/frontmatter.svg)](https://www.npmjs.com/package/@myst-theme/frontmatter)
4
- [![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/curvenote/curvenote/blob/main/LICENSE)
4
+ [![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/jupyter-book/myst-theme/blob/main/LICENSE)
5
5
 
6
- Convert a MyST AST to React.
6
+ React components for rendering MyST frontmatter.
@@ -1 +1 @@
1
- {"version":3,"file":"LaunchButton.d.ts","sourceRoot":"","sources":["../src/LaunchButton.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,wBAAwB,EAAoB,MAAM,kBAAkB,CAAC;AAiDnF,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,wBAAwB,CAAC;IAChC,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAmVF,wBAAgB,YAAY,CAAC,KAAK,EAAE,WAAW,2CAyD9C"}
1
+ {"version":3,"file":"LaunchButton.d.ts","sourceRoot":"","sources":["../src/LaunchButton.tsx"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,wBAAwB,EAAoB,MAAM,kBAAkB,CAAC;AAmEnF,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,wBAAwB,CAAC;IAChC,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAkeF,wBAAgB,YAAY,CAAC,KAAK,EAAE,WAAW,2CAiC9C"}
@@ -1,31 +1,52 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
1
10
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useRef, useCallback, useState } from 'react';
11
+ import React, { useRef, useCallback, useState } from 'react';
3
12
  import classNames from 'classnames';
4
13
  import * as Popover from '@radix-ui/react-popover';
5
- import { RocketIcon, Cross2Icon, ClipboardCopyIcon, ExternalLinkIcon } from '@radix-ui/react-icons';
6
- import * as Tabs from '@radix-ui/react-tabs';
14
+ import { RocketIcon, Cross2Icon, ClipboardCopyIcon, ExternalLinkIcon, QuestionMarkCircledIcon, UpdateIcon, Link2Icon, } from '@radix-ui/react-icons';
15
+ import { ChevronRightIcon } from '@heroicons/react/24/solid';
16
+ import { BinderIcon, JupyterIcon } from '@scienceicons/react/24/solid';
7
17
  import * as Form from '@radix-ui/react-form';
8
18
  const GITHUB_USERNAME_REPO_REGEX = /^(?:https?:\/\/github.com\/)?([A-Za-z0-9_.-]+)\/([A-Za-z0-9_.-]+)(?:.git)?\/?$/;
9
19
  const GITLAB_USERNAME_REPO_REGEX = /^(?:https?:\/\/gitlab.com\/)?([A-Za-z0-9_.-]+)\/([A-Za-z0-9_.-]+)(?:.git)?\/?$/;
10
20
  const GIST_USERNAME_REPO_REGEX = /^(?:https?:\/\/gist.github.com\/)?([A-Za-z0-9_.-]+)\/([A-Za-z0-9_.-]+)(?:.git)?\/?$/;
21
+ /**
22
+ * Component to add a copy-to-clipboard button
23
+ */
11
24
  function CopyButton(props) {
12
- const { className, defaultMessage, alternateMessage, buildLink, timeout } = props;
25
+ const { className, defaultMessage, copiedMessage, invalidLinkFallback, buildLink, copiedMessageDuration, } = props;
13
26
  const [message, setMessage] = useState(defaultMessage);
14
27
  const copyLink = useCallback(() => {
15
- // Build the link for the clipboard
16
- const link = props.buildLink();
28
+ var _a;
17
29
  // In secure links, we can copy it!
18
30
  if (window.isSecureContext) {
31
+ // Build the link for the clipboard
32
+ const link = props.buildLink();
19
33
  // Write to clipboard
20
- window.navigator.clipboard.writeText(link !== null && link !== void 0 ? link : '<invalid link>');
34
+ window.navigator.clipboard.writeText((_a = link !== null && link !== void 0 ? link : invalidLinkFallback) !== null && _a !== void 0 ? _a : '<invalid link>');
21
35
  // Update UI
22
- setMessage(alternateMessage !== null && alternateMessage !== void 0 ? alternateMessage : defaultMessage);
36
+ setMessage(copiedMessage !== null && copiedMessage !== void 0 ? copiedMessage : defaultMessage);
23
37
  // Set callback to restore message
24
38
  setTimeout(() => {
25
39
  setMessage(defaultMessage);
26
- }, timeout !== null && timeout !== void 0 ? timeout : 1000);
40
+ }, copiedMessageDuration !== null && copiedMessageDuration !== void 0 ? copiedMessageDuration : 1000);
27
41
  }
28
- }, [defaultMessage, alternateMessage, buildLink, timeout, setMessage]);
42
+ }, [
43
+ defaultMessage,
44
+ copiedMessage,
45
+ buildLink,
46
+ copiedMessageDuration,
47
+ invalidLinkFallback,
48
+ setMessage,
49
+ ]);
29
50
  return (_jsxs("button", { type: "button", className: classNames(className, 'flex flex-row items-center gap-1'), onClick: copyLink, children: [message, " ", _jsx(ClipboardCopyIcon, { className: "inline-block" })] }));
30
51
  }
31
52
  /**
@@ -181,11 +202,66 @@ function makeNbgitpullerURL(options, location) {
181
202
  });
182
203
  return `git-pull?${query}`;
183
204
  }
184
- function BinderLaunchContent(props) {
205
+ function useDebounce(value, delay) {
206
+ const [debouncedValue, setDebouncedValue] = useState(value);
207
+ React.useEffect(() => {
208
+ const handle = setTimeout(() => {
209
+ setDebouncedValue(value);
210
+ }, delay);
211
+ return () => {
212
+ clearTimeout(handle);
213
+ };
214
+ }, [value, delay]);
215
+ return debouncedValue;
216
+ }
217
+ /**
218
+ * Interrogate a possible remote provider URL to
219
+ * determine whether it is a BinderHub or JupyterHub
220
+ *
221
+ * @param baseUrl - URL to interrogate, ending with a slash
222
+ */
223
+ function interrogateProviderType(baseUrl) {
224
+ return __awaiter(this, void 0, void 0, function* () {
225
+ const binderURL = `${baseUrl}versions`;
226
+ try {
227
+ const response = yield fetch(binderURL);
228
+ const data = yield response.json();
229
+ if ('binderhub' in data) {
230
+ return 'binderhub';
231
+ }
232
+ }
233
+ catch (err) {
234
+ console.debug(`Couldn't reach ${binderURL}`);
235
+ }
236
+ const hubURL = `${baseUrl}hub/api/`;
237
+ try {
238
+ const response = yield fetch(hubURL);
239
+ const data = yield response.json();
240
+ if ('version' in data) {
241
+ return 'jupyterhub';
242
+ }
243
+ }
244
+ catch (err) {
245
+ console.debug(`Couldn't reach ${binderURL}`);
246
+ }
247
+ return 'error';
248
+ });
249
+ }
250
+ function DetectLaunchContent(props) {
185
251
  var _a;
186
252
  const { thebe, location, onLaunch } = props;
187
253
  const { binder } = thebe;
188
254
  const defaultBinderBaseURL = (_a = binder === null || binder === void 0 ? void 0 : binder.url) !== null && _a !== void 0 ? _a : 'https://mybinder.org';
255
+ // Detect the provider type
256
+ const [detectedProviderType, setDetectedProviderType] = useState(undefined);
257
+ // Handle URL entry that needs to be debounced
258
+ const [url, setURL] = useState('');
259
+ const onUrlChanged = useCallback((event) => {
260
+ // Reset the known state of the provider
261
+ setDetectedProviderType(undefined);
262
+ // Update the recorded state of the URL input
263
+ setURL(event.target.value);
264
+ }, [setURL]);
189
265
  const formRef = useRef(null);
190
266
  const buildLink = useCallback(() => {
191
267
  const form = formRef.current;
@@ -193,8 +269,26 @@ function BinderLaunchContent(props) {
193
269
  return;
194
270
  }
195
271
  const data = Object.fromEntries(new FormData(form));
196
- return makeBinderURL(Object.assign(Object.assign({}, (binder !== null && binder !== void 0 ? binder : {})), { url: data.url || defaultBinderBaseURL }), location);
197
- }, [formRef, location, binder]);
272
+ const rawBaseUrl = data.url;
273
+ if (!rawBaseUrl) {
274
+ return;
275
+ }
276
+ const baseUrl = ensureBasename(rawBaseUrl);
277
+ const userProvider = data === null || data === void 0 ? void 0 : data.provider;
278
+ const provider = userProvider !== null && userProvider !== void 0 ? userProvider : detectedProviderType;
279
+ switch (provider) {
280
+ case 'jupyterhub': {
281
+ const gitPullURL = makeNbgitpullerURL(binder !== null && binder !== void 0 ? binder : {}, location);
282
+ return `${baseUrl}hub/user-redirect/${gitPullURL}`;
283
+ }
284
+ case 'binderhub': {
285
+ return makeBinderURL(Object.assign(Object.assign({}, (binder !== null && binder !== void 0 ? binder : {})), { url: baseUrl }), location);
286
+ }
287
+ case undefined: {
288
+ return;
289
+ }
290
+ }
291
+ }, [formRef, location, binder, detectedProviderType]);
198
292
  // FIXME: use ValidityState from radix-ui once passing-by-name is fixed
199
293
  const urlRef = useRef(null);
200
294
  const buildValidLink = useCallback(() => {
@@ -206,48 +300,44 @@ function BinderLaunchContent(props) {
206
300
  return buildLink();
207
301
  }
208
302
  }, [buildLink, urlRef]);
209
- const handleSubmit = useCallback((event) => {
210
- var _a;
211
- event.preventDefault();
212
- const link = buildLink();
213
- // Link should exist, but guard anyway
214
- if (link) {
215
- (_a = window === null || window === void 0 ? void 0 : window.open(link, '_blank')) === null || _a === void 0 ? void 0 : _a.focus();
216
- }
217
- onLaunch === null || onLaunch === void 0 ? void 0 : onLaunch();
218
- }, [defaultBinderBaseURL, buildLink, onLaunch]);
219
- return (_jsxs(Form.Root, { className: "w-[260px]", onSubmit: handleSubmit, ref: formRef, children: [_jsxs("p", { className: "mb-2.5 text-[15px] font-medium leading-[19px]", children: ["Launch on a BinderHub e.g. ", _jsx("a", { href: "https://mybinder.org", children: "mybinder.org" })] }), _jsxs(Form.Field, { className: "mb-2.5 grid", name: "url", children: [_jsxs("div", { className: "flex items-baseline justify-between", children: [_jsx(Form.Label, { className: "text-[15px] font-medium leading-[35px]", children: "BinderHub URL" }), _jsx(Form.Message, { className: "text-[13px] opacity-80", match: "typeMismatch", children: "Please provide a valid URL that starts with http(s)." })] }), _jsx(Form.Control, { asChild: true, children: _jsx("input", { className: "box-border inline-flex h-[35px] w-full appearance-none items-center justify-center rounded px-2.5 text-[15px] leading-none shadow-[0_0_0_1px] shadow-slate-400 outline-none bg-gray-50 dark:bg-gray-700 hover:shadow-[0_0_0_1px_black] focus:shadow-[0_0_0_2px_black]", type: "url", placeholder: defaultBinderBaseURL, ref: urlRef }) })] }), _jsxs("div", { className: "flex flex-row justify-between", children: [_jsx(Form.Submit, { asChild: true, children: _jsxs("button", { className: "inline-flex flex-row gap-1 h-[35px] items-center justify-center rounded px-[15px] font-medium leading-none bg-orange-500 hover:bg-orange-600 outline-none text-white focus:shadow-[0_0_0_2px] focus:shadow-black focus:outline-none", children: [_jsx("span", { children: "Launch" }), " ", _jsx(ExternalLinkIcon, { className: "inline-block" })] }) }), _jsx(CopyButton, { className: "inline-flex h-[35px] items-center justify-center rounded px-[15px] font-medium leading-none bg-gray-400 hover:bg-gray-500 outline-none text-white focus:shadow-[0_0_0_2px] focus:shadow-black focus:outline-none", defaultMessage: "Copy Link", alternateMessage: "Copied Link", buildLink: buildValidLink })] })] }));
220
- }
221
- function JupyterHubLaunchContent(props) {
222
- const { onLaunch, location, thebe } = props;
223
- const { binder } = thebe;
224
- const defaultHubBaseURL = '';
225
- const formRef = useRef(null);
226
- const buildLink = useCallback(() => {
227
- const form = formRef.current;
228
- if (!form) {
303
+ // Detect the provider type on debounced text input
304
+ const debouncedURL = useDebounce(url, 100);
305
+ const [isInterrogating, setIsInterrogating] = useState(false);
306
+ React.useEffect(() => {
307
+ var _a, _b;
308
+ // Check validity manually to ensure that we don't make requests that aren't sensible
309
+ const urlIsValid = !!((_b = (_a = urlRef.current) === null || _a === void 0 ? void 0 : _a.checkValidity) === null || _b === void 0 ? void 0 : _b.call(_a));
310
+ // Don't detect URL if it isn't valid
311
+ if (!urlIsValid) {
229
312
  return;
230
313
  }
231
- const data = Object.fromEntries(new FormData(form));
232
- const rawHubBaseURL = data.url;
233
- if (!rawHubBaseURL) {
234
- return;
314
+ // Enter interrogating state
315
+ setIsInterrogating(true);
316
+ // Interrogate remote endpoint
317
+ let baseName;
318
+ try {
319
+ baseName = ensureBasename(debouncedURL);
235
320
  }
236
- const gitPullURL = makeNbgitpullerURL(binder !== null && binder !== void 0 ? binder : {}, location);
237
- const hubURL = ensureBasename(rawHubBaseURL);
238
- return `${hubURL}hub/user-redirect/${gitPullURL}`;
239
- }, [formRef, location, binder]);
240
- // FIXME: use ValidityState from radix-ui once passing-by-name is fixed
241
- const urlRef = useRef(null);
242
- const buildValidLink = useCallback(() => {
243
- var _a;
244
- if (((_a = urlRef.current) === null || _a === void 0 ? void 0 : _a.dataset.invalid) === 'true') {
321
+ catch (err) {
245
322
  return;
246
323
  }
247
- else {
248
- return buildLink();
249
- }
250
- }, [buildLink, urlRef]);
324
+ interrogateProviderType(baseName)
325
+ .then((provider) => {
326
+ if (provider !== 'error') {
327
+ setDetectedProviderType(provider);
328
+ }
329
+ // Special case for mybinder.org
330
+ else if (/https?:\/\/mybinder.org\//.test(baseName)) {
331
+ setDetectedProviderType('binderhub');
332
+ }
333
+ else {
334
+ setDetectedProviderType('error');
335
+ }
336
+ })
337
+ .catch(console.error)
338
+ // Clear the interrogating state
339
+ .finally(() => setIsInterrogating(false));
340
+ }, [debouncedURL, urlRef, setIsInterrogating]);
251
341
  const handleSubmit = useCallback((event) => {
252
342
  var _a;
253
343
  event.preventDefault();
@@ -257,8 +347,13 @@ function JupyterHubLaunchContent(props) {
257
347
  (_a = window === null || window === void 0 ? void 0 : window.open(link, '_blank')) === null || _a === void 0 ? void 0 : _a.focus();
258
348
  }
259
349
  onLaunch === null || onLaunch === void 0 ? void 0 : onLaunch();
260
- }, [defaultHubBaseURL, buildLink, onLaunch]);
261
- return (_jsxs(Form.Root, { className: "w-[260px]", onSubmit: handleSubmit, ref: formRef, children: [_jsx("p", { className: "mb-2.5 text-[15px] font-medium leading-[19px]", children: "Launch on a JupyterHub" }), _jsxs(Form.Field, { className: "mb-2.5 grid", name: "url", children: [_jsxs("div", { className: "flex items-baseline justify-between", children: [_jsx(Form.Label, { className: "text-[15px] font-medium leading-[35px]", children: "JupyterHub URL" }), _jsx(Form.Message, { className: "text-[13px] opacity-80", match: "valueMissing", children: "Please provide a URL." }), _jsx(Form.Message, { className: "text-[13px] opacity-80", match: "typeMismatch", children: "Please provide a valid URL that starts with http(s)." })] }), _jsx(Form.Control, { asChild: true, children: _jsx("input", { className: "box-border inline-flex h-[35px] w-full appearance-none items-center justify-center rounded px-2.5 text-[15px] leading-none shadow-[0_0_0_1px] shadow-slate-400 outline-none bg-gray-50 dark:bg-gray-700 hover:shadow-[0_0_0_1px_black] focus:shadow-[0_0_0_2px_black]", type: "url", required: true, ref: urlRef }) })] }), _jsxs("div", { className: "flex flex-row justify-between", children: [_jsx(Form.Submit, { asChild: true, children: _jsxs("button", { className: "inline-flex flex-row gap-1 h-[35px] items-center justify-center rounded px-[15px] font-medium leading-none bg-orange-500 hover:bg-orange-600 outline-none text-white focus:shadow-[0_0_0_2px] focus:shadow-black focus:outline-none", children: [_jsx("span", { children: "Launch" }), " ", _jsx(ExternalLinkIcon, { className: "inline-block" })] }) }), _jsx(CopyButton, { className: "inline-flex h-[35px] items-center justify-center rounded px-[15px] font-medium leading-none bg-gray-400 hover:bg-gray-500 outline-none text-white focus:shadow-[0_0_0_2px] focus:shadow-black focus:outline-none", defaultMessage: "Copy Link", alternateMessage: "Copied Link", buildLink: buildValidLink })] })] }));
350
+ }, [defaultBinderBaseURL, buildLink, onLaunch]);
351
+ return (_jsxs(Form.Root, { onSubmit: handleSubmit, ref: formRef, children: [_jsxs(Form.Field, { className: "mb-2.5 grid", name: "url", children: [_jsxs("div", { className: "flex flex-col items-baseline justify-between", children: [_jsxs(Form.Label, { className: "text-[15px] font-medium leading-[35px]", children: ["Enter a JupyterHub or BinderHub URL, e.g.", ' ', _jsx("a", { href: "https://mybinder.org", className: "font-medium text-blue-600 dark:text-blue-500 hover:underline", children: "https://mybinder.org" })] }), _jsx(Form.Message, { className: "text-[13px] opacity-80", match: "typeMismatch", children: "Please provide a valid URL that starts with http(s)." })] }), _jsxs("div", { className: "relative flex", children: [_jsx("span", { className: "flex absolute h-full", "aria-hidden": true, children: (detectedProviderType === 'binderhub' && (_jsx(BinderIcon, { className: "w-[24px] h-[24px] mx-[4px] self-center pointer-events-none" }))) ||
352
+ (detectedProviderType === 'jupyterhub' && (_jsx(JupyterIcon, { className: "w-[24px] h-[24px] mx-[4px] self-center pointer-events-none" }))) ||
353
+ (detectedProviderType === 'error' && (_jsx(QuestionMarkCircledIcon, { className: "w-[24px] h-[24px] mx-[4px] self-center pointer-events-none" }))) ||
354
+ (isInterrogating && (_jsx(UpdateIcon, { className: "w-[24px] h-[24px] mx-[4px] self-center pointer-events-none motion-safe:animate-spin" }))) || (_jsx(Link2Icon, { className: "w-[24px] h-[24px] mx-[4px] self-center pointer-events-none" })) }), _jsx(Form.Control, { asChild: true, children: _jsx("input", { className: "ps-[32px] box-border inline-flex h-[35px] w-full appearance-none items-center justify-center rounded px-2.5 text-[15px] leading-none shadow-[0_0_0_1px] shadow-slate-400 outline-none bg-gray-50 dark:bg-gray-700 hover:shadow-[0_0_0_1px_black] focus:shadow-[0_0_0_2px_black]", type: "url", placeholder: defaultBinderBaseURL, required: true, ref: urlRef, onChange: onUrlChanged }) })] })] }), _jsxs("details", { className: classNames('rounded-md my-5 shadow dark:shadow-2xl dark:shadow-neutral-900 overflow-hidden', 'bg-gray-50 dark:bg-stone-800', { hidden: !(detectedProviderType === 'jupyterhub' || detectedProviderType === 'error') }), open: false, children: [_jsx("summary", { className: classNames('m-0 text-lg font-medium py-1 min-h-[2em] pl-3', 'cursor-pointer hover:shadow-[inset_0_0_0px_30px_#00000003] dark:hover:shadow-[inset_0_0_0px_30px_#FFFFFF03]', 'bg-gray-100 dark:bg-slate-900'), children: _jsxs("span", { className: "text-neutral-900 dark:text-white", children: [_jsx("span", { className: "block float-right text-sm font-thin text-neutral-700 dark:text-neutral-200", children: _jsx(ChevronRightIcon, { width: "1.5rem", height: "1.5rem", className: classNames('details-toggle', 'transition-transform') }) }), "JupyterHub Requirements"] }) }), _jsxs("div", { className: "px-4 py-1 details-body flex flex-col gap-1", children: [_jsx("p", { children: "Launching on a JupyterHub will usually require you to choose a \"profile\". You should select a profile that has the right packages, and enough resources to run the code-cells and inline expressions in this MyST project." }), _jsxs("p", { children: ["Whichever image you choose, it must have the", ' ', _jsx("a", { href: "https://github.com/jupyterhub/nbgitpuller", className: "underline", children: "nbgitpuller" }), ' ', "extension installed. If it is missing, you will see an HTTP 404 error once the server starts."] }), _jsx("p", { children: "Contact the Hub administrator for more information about using nbgitpuller with JupyterHub." })] })] }), _jsxs("fieldset", { disabled: detectedProviderType !== 'error', className: classNames('mt-6', { hidden: detectedProviderType !== 'error' }), children: [_jsx("legend", { className: "mb-3", children: "The provider type could not be detected automatically. what kind of provider have you given?" }), _jsxs("div", { children: [_jsx("input", { id: "jupyterhub", type: "radio", name: "provider", value: "jupyterhub", className: "mr-2", defaultChecked: true }), _jsx("label", { className: "cursor-pointer ", htmlFor: "jupyterhub", children: "JupyterHub" })] }), _jsxs("div", { children: [_jsx("input", { id: "binderhub", type: "radio", name: "provider", className: "mr-2", value: "binderhub" }), _jsx("label", { className: "cursor-pointer ", htmlFor: "binderhub", children: "BinderHub" })] })] }), _jsxs("fieldset", { className: classNames('flex flex-row justify-between mt-6', {
355
+ hidden: detectedProviderType === undefined,
356
+ }), disabled: detectedProviderType === undefined, children: [_jsx(Form.Submit, { asChild: true, children: _jsxs("button", { className: "inline-flex flex-row gap-1 h-[35px] items-center justify-center rounded px-[15px] font-medium leading-none bg-orange-500 hover:bg-orange-600 outline-none text-white focus:shadow-[0_0_0_2px] focus:shadow-black focus:outline-none", children: [_jsx("span", { children: "Launch" }), " ", _jsx(ExternalLinkIcon, { className: "inline-block" })] }) }), _jsx(CopyButton, { className: "inline-flex h-[35px] items-center justify-center rounded px-[15px] font-medium leading-none bg-gray-400 hover:bg-gray-500 outline-none text-white focus:shadow-[0_0_0_2px] focus:shadow-black focus:outline-none", defaultMessage: "Copy Link", copiedMessage: "Link Copied", buildLink: buildValidLink })] })] }));
262
357
  }
263
358
  export function LaunchButton(props) {
264
359
  const closeRef = useRef(null);
@@ -266,5 +361,5 @@ export function LaunchButton(props) {
266
361
  var _a, _b;
267
362
  (_b = (_a = closeRef.current) === null || _a === void 0 ? void 0 : _a.click) === null || _b === void 0 ? void 0 : _b.call(_a);
268
363
  }, []);
269
- return (_jsxs(Popover.Root, { children: [_jsx(Popover.Trigger, { asChild: true, children: _jsx("button", { className: "inline-flex size-[24px] hover:text-[#E18435] items-center justify-center", "aria-label": "Launch in external computing interface", children: _jsx(RocketIcon, {}) }) }), _jsx(Popover.Portal, { children: _jsxs(Popover.Content, { className: "z-30 text-gray-700 dark:text-white bg-white dark:bg-stone-800 p-5 rounded shadow-[0_10px_38px_-10px_hsla(206,22%,7%,.35),0_10px_20px_-15px_hsla(206,22%,7%,.2)]", sideOffset: 5, children: [_jsxs(Tabs.Root, { className: "flex w-[300px] flex-col", defaultValue: "binder", children: [_jsxs(Tabs.List, { className: "flex shrink-0 border-b divide-x border-gray-200 dark:border-gray-400", "aria-label": "Launch into computing interface", children: [_jsx(Tabs.Trigger, { className: "flex h-[45px] flex-1 cursor-default items-center justify-center px-5 text-[15px] outline-none data-[state=active]:underline border-gray-200 dark:border-gray-400", value: "binder", children: "Binder" }), _jsx(Tabs.Trigger, { className: "flex h-[45px] flex-1 cursor-default items-center justify-center px-5 text-[15px] outline-none data-[state=active]:underline border-gray-200 dark:border-gray-400", value: "jupyterhub", children: "JupyterHub" })] }), _jsx(Tabs.Content, { className: "grow rounded-b-md p-5 outline-none", value: "binder", children: _jsx(BinderLaunchContent, Object.assign({}, props, { onLaunch: closePopover })) }), _jsx(Tabs.Content, { className: "grow rounded-b-md p-5 outline-none", value: "jupyterhub", children: _jsx(JupyterHubLaunchContent, Object.assign({}, props, { onLaunch: closePopover })) })] }), _jsx(Popover.Close, { className: "absolute right-[5px] top-[5px] inline-flex size-[25px] items-center justify-center rounded-full", "aria-label": "Close", ref: closeRef, children: _jsx(Cross2Icon, {}) }), _jsx(Popover.Arrow, { className: "fill-white" })] }) })] }));
364
+ return (_jsxs(Popover.Root, { children: [_jsx(Popover.Trigger, { asChild: true, children: _jsx("button", { className: "inline-flex size-[24px] hover:text-[#E18435] items-center justify-center", "aria-label": "Launch in external computing interface", children: _jsx(RocketIcon, {}) }) }), _jsx(Popover.Portal, { children: _jsxs(Popover.Content, { className: "z-30 text-gray-700 dark:text-white bg-white dark:bg-stone-800 p-5 rounded shadow-[0_10px_38px_-10px_hsla(206,22%,7%,.35),0_10px_20px_-15px_hsla(206,22%,7%,.2)] max-w-[400px]", sideOffset: 5, children: [_jsx(DetectLaunchContent, Object.assign({}, props, { onLaunch: closePopover })), _jsx(Popover.Close, { className: "absolute right-[5px] top-[5px] inline-flex size-[25px] items-center justify-center rounded-full", "aria-label": "Close", ref: closeRef, children: _jsx(Cross2Icon, {}) }), _jsx(Popover.Arrow, { className: "fill-white" })] }) })] }));
270
365
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@myst-theme/frontmatter",
3
- "version": "0.14.0",
3
+ "version": "0.14.2",
4
4
  "type": "module",
5
5
  "exports": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -25,8 +25,7 @@
25
25
  "@radix-ui/react-form": "^0.1.0",
26
26
  "@radix-ui/react-icons": "^1.3.2",
27
27
  "@radix-ui/react-popover": "^1.1.2",
28
- "@radix-ui/react-tabs": "^1.1.1",
29
- "@scienceicons/react": "^0.0.6",
28
+ "@scienceicons/react": "^0.0.12",
30
29
  "classnames": "^2.3.2",
31
30
  "myst-common": "*",
32
31
  "myst-frontmatter": "*"