Skip to content

Commit

Permalink
on an island in the sun
Browse files Browse the repository at this point in the history
  • Loading branch information
nonrational committed Oct 21, 2024
1 parent 46eabb8 commit 77cb418
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 20 deletions.
6 changes: 4 additions & 2 deletions fresh.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import * as $_404 from './routes/_404.tsx'
import * as $_app from './routes/_app.tsx'
import * as $api_agents from './routes/api/agents.ts'
import * as $index from './routes/index.tsx'

import * as $ua_input from './islands/ua-input.tsx'
import type { Manifest } from '$fresh/server.ts'

const manifest = {
Expand All @@ -16,7 +16,9 @@ const manifest = {
'./routes/api/agents.ts': $api_agents,
'./routes/index.tsx': $index,
},
islands: {},
islands: {
'./islands/ua-input.tsx': $ua_input,
},
baseUrl: import.meta.url,
} satisfies Manifest

Expand Down
25 changes: 25 additions & 0 deletions islands/ua-input.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// With compliments to Creative Tim – https://www.creative-tim.com?ref=tailwindcomponents
const UaInputSubmit = ({ ok, value }: { ok: boolean; value?: string }) => {
return (
<div class='relative flex h-10 w-full min-w-[200px] max-w-4xl'>
<button
class='!absolute right-1 top-1 z-10 select-none rounded bg-slate-300 py-2 px-4 text-center align-middle font-sans text-xs font-bold uppercase text-white shadow-md shadow-slate-300/20 transition-all hover:shadow-lg hover:shadow-slate-300/40 focus:opacity-[0.85] focus:shadow-none active:opacity-[0.85] active:shadow-none peer-placeholder-shown:pointer-events-none peer-placeholder-shown:bg-blue-gray-500 peer-placeholder-shown:opacity-50 peer-placeholder-shown:shadow-none'
type='submit'
>
<span style={{ textShadow: '0 0 2px white' }}>🔍</span>
</button>
<input
class='peer h-full w-full rounded-[7px] border border-blue-gray-200 bg-transparent px-3 py-2.5 pr-20 font-sans text-sm font-normal text-blue-gray-700 outline outline-0 transition-all placeholder-shown:border placeholder-shown:border-blue-gray-200 placeholder-shown:border-t-blue-gray-200 focus:border-2 focus:border-slate-300 focus:border-t-transparent focus:outline-0 disabled:border-0 disabled:bg-blue-gray-50'
name='ua'
value={value}
style={{ width: '100%', wordBreak: 'break-word', resize: 'both', borderColor: ok ? null : '#b91c1c' }}
onClick={(e) => e.currentTarget.select()}
/>
<label class="before:content[' '] after:content[' '] pointer-events-none absolute left-0 -top-1.5 flex h-full w-full select-none text-[11px] font-normal leading-tight text-blue-gray-400 transition-all before:pointer-events-none before:mt-[6.5px] before:mr-1 before:box-border before:block before:h-1.5 before:w-2.5 before:rounded-tl-md before:border-t before:border-l before:border-blue-gray-200 before:transition-all after:pointer-events-none after:mt-[6.5px] after:ml-1 after:box-border after:block after:h-1.5 after:w-2.5 after:flex-grow after:rounded-tr-md after:border-t after:border-r after:border-blue-gray-200 after:transition-all peer-placeholder-shown:text-sm peer-placeholder-shown:leading-[3.75] peer-placeholder-shown:text-blue-gray-500 peer-placeholder-shown:before:border-transparent peer-placeholder-shown:after:border-transparent peer-focus:text-[11px] peer-focus:leading-tight peer-focus:text-slate-300 peer-focus:before:border-t-2 peer-focus:before:border-l-2 peer-focus:before:!border-slate-300 peer-focus:after:border-t-2 peer-focus:after:border-r-2 peer-focus:after:!border-slate-300 peer-disabled:text-transparent peer-disabled:before:border-transparent peer-disabled:after:border-transparent peer-disabled:peer-placeholder-shown:text-blue-gray-500">
User Agent
</label>
</div>
)
}

export default UaInputSubmit
2 changes: 1 addition & 1 deletion lib/agent.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import data, { type AgentLiteKey, type UsageFloat, type Version } from './caniuse_lite.ts'
import data, { type AgentLiteKey, type UsageFloat, type Version } from './caniuse-lite.ts'
import { UserAgent } from '$std/http/user_agent.ts'
import { epochToDate } from './utils.ts'
import { getFamilyName } from './family.ts'
Expand Down
File renamed without changes.
5 changes: 4 additions & 1 deletion routes/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ export default function App({ Component }: PageProps) {
<meta charset='utf-8' />
<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0' />
<title>user-agent.info</title>

<link rel='stylesheet' href='https://unpkg.com/@material-tailwind/html@latest/styles/material-tailwind.css' />
<link rel='stylesheet' href='/styles.css' />

<link rel='preconnect' href='https://fonts.googleapis.com' />
<link rel='preconnect' href='https://fonts.gstatic.com' crossorigin='true' />
<link href='https://fonts.googleapis.com/css2?family=Merienda:[email protected]&display=swap' rel='stylesheet' />
<link rel='stylesheet' href='https://fonts.googleapis.com/css2?family=Merienda:[email protected]&display=swap' />
</head>
<body>
<Component />
Expand Down
37 changes: 21 additions & 16 deletions routes/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { type AgentRelease, getAgentReleaseInfo } from '../lib/agent.ts'
import { formatDateYearMonth, humanizedTimeSince, randInterjection, toOrdinal } from '../lib/utils.ts'
import { getFamilyName, getGlobalUsageStats, getNorthAmericaUsageStats } from '../lib/family.ts'
import manver, { type ManVer } from '../lib/manver.ts'
import UaInputSubmit from '../islands/ua-input.tsx'
import type { UserAgent } from '$std/http/user_agent.ts'

export type KnownBrowserName = string

Expand Down Expand Up @@ -96,11 +98,23 @@ const UsageStats = ({ deviceType, userAgent, version, name, usage, currentVersio
)
}

// Because we're going to set innerHTML, only render
const FormattedUserAgent = ({ userAgent }: { userAgent?: UserAgent }) => {
if (!userAgent) return null

const uaParts = userAgent.ua.replace(/([A-z]+\/[0-9.]+)/g, '¶$1').split('¶')

return (
<code class='block my-4 text-sm break-word text-center'>
{uaParts.map((part, index) => <div key={`ua-${index}`}>{part}</div>)}
</code>
)
}

const Home: FunctionalComponent<HomeProps> = ({ data }: PageProps) => {
const { ok, source, ua, userAgent } = data as RenderData
const { ok, ua, userAgent } = data as RenderData

const inputValue = source === 'query' ? (ok ? userAgent?.ua : ua) : undefined
const inputPlaceholder = source === 'header' ? (ok ? userAgent?.ua : ua) : undefined
const inputValue = ok ? userAgent?.ua : ua

return (
<div class='container mx-auto flex flex-col items-center justify-center max-w-xs sm:max-w-sm md:max-w-lg lg:max-w-4xl'>
Expand All @@ -110,21 +124,12 @@ const Home: FunctionalComponent<HomeProps> = ({ data }: PageProps) => {
</div>

<form method='GET' style={{ width: '100%', display: 'block', margin: '24px 0' }}>
<input
name='ua'
value={inputValue}
placeholder={inputPlaceholder}
style={{ width: '100%', wordBreak: 'break-word', resize: 'both', borderColor: ok ? null : '#b91c1c' }}
class='bg-gray-50 border border-gray-300 text-gray-900 text-sm p-2.5 mb-4 rounded'
/>
<div class='flex justify-center'>
<button type='submit' class='mx-auto bg-gray-500 hover:bg-gray-700 text-white font-bold py-1 px-4 rounded'>
Submit
</button>
</div>
<UaInputSubmit ok={ok} value={inputValue} />
</form>

<div class='p-lg'>
<FormattedUserAgent userAgent={userAgent} />

<div class='p-8'>
<AgentAck {...data} />

{ok &&
Expand Down

0 comments on commit 77cb418

Please sign in to comment.