Skip to content

Instantly share code, notes, and snippets.

View Temzasse's full-sized avatar

Teemu Taskula Temzasse

View GitHub Profile
@Temzasse
Temzasse / get-text-width.ts
Created March 31, 2025 10:43
Get text width
export function getTextWidth(text: string, element: HTMLElement): number {
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
if (!context) return 0;
const fontWeight = getCssStyle(element, 'font-weight') || 'normal';
const fontSize = getCssStyle(element, 'font-size') || '14px';
const fontFamily = getCssStyle(element, 'font-family') || 'Times New Roman';
const font = `${fontWeight} ${fontSize} ${fontFamily}`;
@Temzasse
Temzasse / get-caret-position.ts
Created March 31, 2025 10:41
Get caret position in input / textarea
const properties = [
'borderTopWidth',
'borderRightWidth',
'borderBottomWidth',
'borderLeftWidth',
'borderStyle',
'boxSizing',
'direction',
'fontFamily',
'fontSize',
@Temzasse
Temzasse / useVirtualKeyboard.tsx
Last active May 14, 2024 08:08
A utility hook that listens to the virtual keyboard appearance and returns the dynamic height of the keyboard.
export function useVirtualKeyboard() {
const [isKeyboardOpen, setKeyboardOpen] = useState(false);
const [keyboardHeight, setKeyboardHeight] = useState(0);
useEffect(() => {
const visualViewport = window.visualViewport;
if (visualViewport) {
const onResize = () => {
const focusedElement = document.activeElement as HTMLElement | null;
@Temzasse
Temzasse / useParsedSearchParams.tsx
Last active April 6, 2024 10:12
A utility hook to parse and type URL search params based on a configuration object. This hook is useful when you want to access URL search params in a typesafe way and with proper casting.
import { useMemo } from "react";
import { useSearchParams } from "react-router-dom";
type ParseConfig = Record<
string,
| { type: "string"; defaultValue?: string }
| { type: "number"; defaultValue?: number }
| { parse: (value: URLSearchParams) => unknown }
>;
@Temzasse
Temzasse / Tabs_example.js
Created November 1, 2017 21:46
An example React.js component for using Tabs component.
import React from 'react';
import Tabs from './Tabs';
const TabsExample = () => (
<Tabs>
<Tabs.Panel label='Tab label 1'>
<h4>Tab content 1</h4>
<p>
Disrupt minimum viable product pivot waterfall is so 2000 and
late viral long shadow cortado SpaceTeam unicorn venture
@Temzasse
Temzasse / Tabs.js
Created November 1, 2017 09:21
A React.js + styled-components Tabs component
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';
import withRipple from './withRipple';
const TabContent = styled.div`
flex: 1;
width: 100%;
`;
@Temzasse
Temzasse / TwerkForm.js
Created August 17, 2017 21:36
Form component with a shake validation gesture.
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import styled, { keyframes } from 'styled-components';
import { darken } from 'polished';
import TextField from './TextField';
const propTypes = {
onAuthSuccess: PropTypes.func.isRequired,
};
@Temzasse
Temzasse / TextField.js
Created August 17, 2017 18:47
TextField with floating label (with styles)
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import styled, { css } from 'styled-components';
import { darken } from 'polished';
const propTypes = {
label: PropTypes.string,
value: PropTypes.string.isRequired,
onChange: PropTypes.func.isRequired,
};
@Temzasse
Temzasse / TextField_no_styles.js
Created August 17, 2017 18:41
TextField with floating label (no styles)
const propTypes = {
label: PropTypes.string,
value: PropTypes.string.isRequired,
onChange: PropTypes.func.isRequired,
};
class TextField extends Component {
state = {
isFocused: false,
}
@Temzasse
Temzasse / Toast.css
Last active June 6, 2017 15:28
CSS animations given to CSSTransitionGroup used inside React.js Toaster component
.toastAnimEnter, .toastAnimAppear {
opacity: 0.01;
transition: opacity .5s cubic-bezier(.03, .83, .76, .98);
}
.toastAnimEnter.toastAnimEnterActive, .toastAnimAppear.toastAnimAppearActive {
opacity: 1;
}
.toastAnimLeave {